/*! jQuery v2.2.4 | (c) jQuery Foundation | jquery.org/license */ ! function (a, b) {
    "object" == typeof module && "object" == typeof module.exports ? module.exports = a.document ? b(a, !0) : function (a) {
        if (!a.document) throw new Error("jQuery requires a window with a document");
        return b(a)
    } : b(a)
}("undefined" != typeof window ? window : this, function (a, b) {
    var c = [],
        d = a.document,
        e = c.slice,
        f = c.concat,
        g = c.push,
        h = c.indexOf,
        i = {},
        j = i.toString,
        k = i.hasOwnProperty,
        l = {},
        m = "2.2.4",
        n = function (a, b) {
            return new n.fn.init(a, b)
        },
        o = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
        p = /^-ms-/,
        q = /-([\da-z])/gi,
        r = function (a, b) {
            return b.toUpperCase()
        };
    n.fn = n.prototype = {
        jquery: m,
        constructor: n,
        selector: "",
        length: 0,
        toArray: function () {
            return e.call(this)
        },
        get: function (a) {
            return null != a ? 0 > a ? this[a + this.length] : this[a] : e.call(this)
        },
        pushStack: function (a) {
            var b = n.merge(this.constructor(), a);
            return b.prevObject = this, b.context = this.context, b
        },
        each: function (a) {
            return n.each(this, a)
        },
        map: function (a) {
            return this.pushStack(n.map(this, function (b, c) {
                return a.call(b, c, b)
            }))
        },
        slice: function () {
            return this.pushStack(e.apply(this, arguments))
        },
        first: function () {
            return this.eq(0)
        },
        last: function () {
            return this.eq(-1)
        },
        eq: function (a) {
            var b = this.length,
                c = +a + (0 > a ? b : 0);
            return this.pushStack(c >= 0 && b > c ? [this[c]] : [])
        },
        end: function () {
            return this.prevObject || this.constructor()
        },
        push: g,
        sort: c.sort,
        splice: c.splice
    }, n.extend = n.fn.extend = function () {
        var a, b, c, d, e, f, g = arguments[0] || {},
            h = 1,
            i = arguments.length,
            j = !1;
        for ("boolean" == typeof g && (j = g, g = arguments[h] || {}, h++), "object" == typeof g || n.isFunction(g) || (g = {}), h === i && (g = this, h--); i > h; h++)
            if (null != (a = arguments[h]))
                for (b in a) c = g[b], d = a[b], g !== d && (j && d && (n.isPlainObject(d) || (e = n.isArray(d))) ? (e ? (e = !1, f = c && n.isArray(c) ? c : []) : f = c && n.isPlainObject(c) ? c : {}, g[b] = n.extend(j, f, d)) : void 0 !== d && (g[b] = d));
        return g
    }, n.extend({
        expando: "jQuery" + (m + Math.random()).replace(/\D/g, ""),
        isReady: !0,
        error: function (a) {
            throw new Error(a)
        },
        noop: function () {},
        isFunction: function (a) {
            return "function" === n.type(a)
        },
        isArray: Array.isArray,
        isWindow: function (a) {
            return null != a && a === a.window
        },
        isNumeric: function (a) {
            var b = a && a.toString();
            return !n.isArray(a) && b - parseFloat(b) + 1 >= 0
        },
        isPlainObject: function (a) {
            var b;
            if ("object" !== n.type(a) || a.nodeType || n.isWindow(a)) return !1;
            if (a.constructor && !k.call(a, "constructor") && !k.call(a.constructor.prototype || {}, "isPrototypeOf")) return !1;
            for (b in a);
            return void 0 === b || k.call(a, b)
        },
        isEmptyObject: function (a) {
            var b;
            for (b in a) return !1;
            return !0
        },
        type: function (a) {
            return null == a ? a + "" : "object" == typeof a || "function" == typeof a ? i[j.call(a)] || "object" : typeof a
        },
        globalEval: function (a) {
            var b, c = eval;
            a = n.trim(a), a && (1 === a.indexOf("use strict") ? (b = d.createElement("script"), b.text = a, d.head.appendChild(b).parentNode.removeChild(b)) : c(a))
        },
        camelCase: function (a) {
            return a.replace(p, "ms-").replace(q, r)
        },
        nodeName: function (a, b) {
            return a.nodeName && a.nodeName.toLowerCase() === b.toLowerCase()
        },
        each: function (a, b) {
            var c, d = 0;
            if (s(a)) {
                for (c = a.length; c > d; d++)
                    if (b.call(a[d], d, a[d]) === !1) break
            } else
                for (d in a)
                    if (b.call(a[d], d, a[d]) === !1) break;
            return a
        },
        trim: function (a) {
            return null == a ? "" : (a + "").replace(o, "")
        },
        makeArray: function (a, b) {
            var c = b || [];
            return null != a && (s(Object(a)) ? n.merge(c, "string" == typeof a ? [a] : a) : g.call(c, a)), c
        },
        inArray: function (a, b, c) {
            return null == b ? -1 : h.call(b, a, c)
        },
        merge: function (a, b) {
            for (var c = +b.length, d = 0, e = a.length; c > d; d++) a[e++] = b[d];
            return a.length = e, a
        },
        grep: function (a, b, c) {
            for (var d, e = [], f = 0, g = a.length, h = !c; g > f; f++) d = !b(a[f], f), d !== h && e.push(a[f]);
            return e
        },
        map: function (a, b, c) {
            var d, e, g = 0,
                h = [];
            if (s(a))
                for (d = a.length; d > g; g++) e = b(a[g], g, c), null != e && h.push(e);
            else
                for (g in a) e = b(a[g], g, c), null != e && h.push(e);
            return f.apply([], h)
        },
        guid: 1,
        proxy: function (a, b) {
            var c, d, f;
            return "string" == typeof b && (c = a[b], b = a, a = c), n.isFunction(a) ? (d = e.call(arguments, 2), f = function () {
                return a.apply(b || this, d.concat(e.call(arguments)))
            }, f.guid = a.guid = a.guid || n.guid++, f) : void 0
        },
        now: Date.now,
        support: l
    }), "function" == typeof Symbol && (n.fn[Symbol.iterator] = c[Symbol.iterator]), n.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "), function (a, b) {
        i["[object " + b + "]"] = b.toLowerCase()
    });

    function s(a) {
        var b = !!a && "length" in a && a.length,
            c = n.type(a);
        return "function" === c || n.isWindow(a) ? !1 : "array" === c || 0 === b || "number" == typeof b && b > 0 && b - 1 in a
    }
    var t = function (a) {
        var b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u = "sizzle" + 1 * new Date,
            v = a.document,
            w = 0,
            x = 0,
            y = ga(),
            z = ga(),
            A = ga(),
            B = function (a, b) {
                return a === b && (l = !0), 0
            },
            C = 1 << 31,
            D = {}.hasOwnProperty,
            E = [],
            F = E.pop,
            G = E.push,
            H = E.push,
            I = E.slice,
            J = function (a, b) {
                for (var c = 0, d = a.length; d > c; c++)
                    if (a[c] === b) return c;
                return -1
            },
            K = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
            L = "[\\x20\\t\\r\\n\\f]",
            M = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
            N = "\\[" + L + "*(" + M + ")(?:" + L + "*([*^$|!~]?=)" + L + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + M + "))|)" + L + "*\\]",
            O = ":(" + M + ")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|" + N + ")*)|.*)\\)|)",
            P = new RegExp(L + "+", "g"),
            Q = new RegExp("^" + L + "+|((?:^|[^\\\\])(?:\\\\.)*)" + L + "+$", "g"),
            R = new RegExp("^" + L + "*," + L + "*"),
            S = new RegExp("^" + L + "*([>+~]|" + L + ")" + L + "*"),
            T = new RegExp("=" + L + "*([^\\]'\"]*?)" + L + "*\\]", "g"),
            U = new RegExp(O),
            V = new RegExp("^" + M + "$"),
            W = {
                ID: new RegExp("^#(" + M + ")"),
                CLASS: new RegExp("^\\.(" + M + ")"),
                TAG: new RegExp("^(" + M + "|[*])"),
                ATTR: new RegExp("^" + N),
                PSEUDO: new RegExp("^" + O),
                CHILD: new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + L + "*(even|odd|(([+-]|)(\\d*)n|)" + L + "*(?:([+-]|)" + L + "*(\\d+)|))" + L + "*\\)|)", "i"),
                bool: new RegExp("^(?:" + K + ")$", "i"),
                needsContext: new RegExp("^" + L + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + L + "*((?:-\\d)?\\d*)" + L + "*\\)|)(?=[^-]|$)", "i")
            },
            X = /^(?:input|select|textarea|button)$/i,
            Y = /^h\d$/i,
            Z = /^[^{]+\{\s*\[native \w/,
            $ = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
            _ = /[+~]/,
            aa = /'|\\/g,
            ba = new RegExp("\\\\([\\da-f]{1,6}" + L + "?|(" + L + ")|.)", "ig"),
            ca = function (a, b, c) {
                var d = "0x" + b - 65536;
                return d !== d || c ? b : 0 > d ? String.fromCharCode(d + 65536) : String.fromCharCode(d >> 10 | 55296, 1023 & d | 56320)
            },
            da = function () {
                m()
            };
        try {
            H.apply(E = I.call(v.childNodes), v.childNodes), E[v.childNodes.length].nodeType
        } catch (ea) {
            H = {
                apply: E.length ? function (a, b) {
                    G.apply(a, I.call(b))
                } : function (a, b) {
                    var c = a.length,
                        d = 0;
                    while (a[c++] = b[d++]);
                    a.length = c - 1
                }
            }
        }

        function fa(a, b, d, e) {
            var f, h, j, k, l, o, r, s, w = b && b.ownerDocument,
                x = b ? b.nodeType : 9;
            if (d = d || [], "string" != typeof a || !a || 1 !== x && 9 !== x && 11 !== x) return d;
            if (!e && ((b ? b.ownerDocument || b : v) !== n && m(b), b = b || n, p)) {
                if (11 !== x && (o = $.exec(a)))
                    if (f = o[1]) {
                        if (9 === x) {
                            if (!(j = b.getElementById(f))) return d;
                            if (j.id === f) return d.push(j), d
                        } else if (w && (j = w.getElementById(f)) && t(b, j) && j.id === f) return d.push(j), d
                    } else {
                        if (o[2]) return H.apply(d, b.getElementsByTagName(a)), d;
                        if ((f = o[3]) && c.getElementsByClassName && b.getElementsByClassName) return H.apply(d, b.getElementsByClassName(f)), d
                    } if (c.qsa && !A[a + " "] && (!q || !q.test(a))) {
                    if (1 !== x) w = b, s = a;
                    else if ("object" !== b.nodeName.toLowerCase()) {
                        (k = b.getAttribute("id")) ? k = k.replace(aa, "\\$&"): b.setAttribute("id", k = u), r = g(a), h = r.length, l = V.test(k) ? "#" + k : "[id='" + k + "']";
                        while (h--) r[h] = l + " " + qa(r[h]);
                        s = r.join(","), w = _.test(a) && oa(b.parentNode) || b
                    }
                    if (s) try {
                        return H.apply(d, w.querySelectorAll(s)), d
                    } catch (y) {} finally {
                        k === u && b.removeAttribute("id")
                    }
                }
            }
            return i(a.replace(Q, "$1"), b, d, e)
        }

        function ga() {
            var a = [];

            function b(c, e) {
                return a.push(c + " ") > d.cacheLength && delete b[a.shift()], b[c + " "] = e
            }
            return b
        }

        function ha(a) {
            return a[u] = !0, a
        }

        function ia(a) {
            var b = n.createElement("div");
            try {
                return !!a(b)
            } catch (c) {
                return !1
            } finally {
                b.parentNode && b.parentNode.removeChild(b), b = null
            }
        }

        function ja(a, b) {
            var c = a.split("|"),
                e = c.length;
            while (e--) d.attrHandle[c[e]] = b
        }

        function ka(a, b) {
            var c = b && a,
                d = c && 1 === a.nodeType && 1 === b.nodeType && (~b.sourceIndex || C) - (~a.sourceIndex || C);
            if (d) return d;
            if (c)
                while (c = c.nextSibling)
                    if (c === b) return -1;
            return a ? 1 : -1
        }

        function la(a) {
            return function (b) {
                var c = b.nodeName.toLowerCase();
                return "input" === c && b.type === a
            }
        }

        function ma(a) {
            return function (b) {
                var c = b.nodeName.toLowerCase();
                return ("input" === c || "button" === c) && b.type === a
            }
        }

        function na(a) {
            return ha(function (b) {
                return b = +b, ha(function (c, d) {
                    var e, f = a([], c.length, b),
                        g = f.length;
                    while (g--) c[e = f[g]] && (c[e] = !(d[e] = c[e]))
                })
            })
        }

        function oa(a) {
            return a && "undefined" != typeof a.getElementsByTagName && a
        }
        c = fa.support = {}, f = fa.isXML = function (a) {
            var b = a && (a.ownerDocument || a).documentElement;
            return b ? "HTML" !== b.nodeName : !1
        }, m = fa.setDocument = function (a) {
            var b, e, g = a ? a.ownerDocument || a : v;
            return g !== n && 9 === g.nodeType && g.documentElement ? (n = g, o = n.documentElement, p = !f(n), (e = n.defaultView) && e.top !== e && (e.addEventListener ? e.addEventListener("unload", da, !1) : e.attachEvent && e.attachEvent("onunload", da)), c.attributes = ia(function (a) {
                return a.className = "i", !a.getAttribute("className")
            }), c.getElementsByTagName = ia(function (a) {
                return a.appendChild(n.createComment("")), !a.getElementsByTagName("*").length
            }), c.getElementsByClassName = Z.test(n.getElementsByClassName), c.getById = ia(function (a) {
                return o.appendChild(a).id = u, !n.getElementsByName || !n.getElementsByName(u).length
            }), c.getById ? (d.find.ID = function (a, b) {
                if ("undefined" != typeof b.getElementById && p) {
                    var c = b.getElementById(a);
                    return c ? [c] : []
                }
            }, d.filter.ID = function (a) {
                var b = a.replace(ba, ca);
                return function (a) {
                    return a.getAttribute("id") === b
                }
            }) : (delete d.find.ID, d.filter.ID = function (a) {
                var b = a.replace(ba, ca);
                return function (a) {
                    var c = "undefined" != typeof a.getAttributeNode && a.getAttributeNode("id");
                    return c && c.value === b
                }
            }), d.find.TAG = c.getElementsByTagName ? function (a, b) {
                return "undefined" != typeof b.getElementsByTagName ? b.getElementsByTagName(a) : c.qsa ? b.querySelectorAll(a) : void 0
            } : function (a, b) {
                var c, d = [],
                    e = 0,
                    f = b.getElementsByTagName(a);
                if ("*" === a) {
                    while (c = f[e++]) 1 === c.nodeType && d.push(c);
                    return d
                }
                return f
            }, d.find.CLASS = c.getElementsByClassName && function (a, b) {
                return "undefined" != typeof b.getElementsByClassName && p ? b.getElementsByClassName(a) : void 0
            }, r = [], q = [], (c.qsa = Z.test(n.querySelectorAll)) && (ia(function (a) {
                o.appendChild(a).innerHTML = "<a id='" + u + "'></a><select id='" + u + "-\r\\' msallowcapture=''><option selected=''></option></select>", a.querySelectorAll("[msallowcapture^='']").length && q.push("[*^$]=" + L + "*(?:''|\"\")"), a.querySelectorAll("[selected]").length || q.push("\\[" + L + "*(?:value|" + K + ")"), a.querySelectorAll("[id~=" + u + "-]").length || q.push("~="), a.querySelectorAll(":checked").length || q.push(":checked"), a.querySelectorAll("a#" + u + "+*").length || q.push(".#.+[+~]")
            }), ia(function (a) {
                var b = n.createElement("input");
                b.setAttribute("type", "hidden"), a.appendChild(b).setAttribute("name", "D"), a.querySelectorAll("[name=d]").length && q.push("name" + L + "*[*^$|!~]?="), a.querySelectorAll(":enabled").length || q.push(":enabled", ":disabled"), a.querySelectorAll("*,:x"), q.push(",.*:")
            })), (c.matchesSelector = Z.test(s = o.matches || o.webkitMatchesSelector || o.mozMatchesSelector || o.oMatchesSelector || o.msMatchesSelector)) && ia(function (a) {
                c.disconnectedMatch = s.call(a, "div"), s.call(a, "[s!='']:x"), r.push("!=", O)
            }), q = q.length && new RegExp(q.join("|")), r = r.length && new RegExp(r.join("|")), b = Z.test(o.compareDocumentPosition), t = b || Z.test(o.contains) ? function (a, b) {
                var c = 9 === a.nodeType ? a.documentElement : a,
                    d = b && b.parentNode;
                return a === d || !(!d || 1 !== d.nodeType || !(c.contains ? c.contains(d) : a.compareDocumentPosition && 16 & a.compareDocumentPosition(d)))
            } : function (a, b) {
                if (b)
                    while (b = b.parentNode)
                        if (b === a) return !0;
                return !1
            }, B = b ? function (a, b) {
                if (a === b) return l = !0, 0;
                var d = !a.compareDocumentPosition - !b.compareDocumentPosition;
                return d ? d : (d = (a.ownerDocument || a) === (b.ownerDocument || b) ? a.compareDocumentPosition(b) : 1, 1 & d || !c.sortDetached && b.compareDocumentPosition(a) === d ? a === n || a.ownerDocument === v && t(v, a) ? -1 : b === n || b.ownerDocument === v && t(v, b) ? 1 : k ? J(k, a) - J(k, b) : 0 : 4 & d ? -1 : 1)
            } : function (a, b) {
                if (a === b) return l = !0, 0;
                var c, d = 0,
                    e = a.parentNode,
                    f = b.parentNode,
                    g = [a],
                    h = [b];
                if (!e || !f) return a === n ? -1 : b === n ? 1 : e ? -1 : f ? 1 : k ? J(k, a) - J(k, b) : 0;
                if (e === f) return ka(a, b);
                c = a;
                while (c = c.parentNode) g.unshift(c);
                c = b;
                while (c = c.parentNode) h.unshift(c);
                while (g[d] === h[d]) d++;
                return d ? ka(g[d], h[d]) : g[d] === v ? -1 : h[d] === v ? 1 : 0
            }, n) : n
        }, fa.matches = function (a, b) {
            return fa(a, null, null, b)
        }, fa.matchesSelector = function (a, b) {
            if ((a.ownerDocument || a) !== n && m(a), b = b.replace(T, "='$1']"), c.matchesSelector && p && !A[b + " "] && (!r || !r.test(b)) && (!q || !q.test(b))) try {
                var d = s.call(a, b);
                if (d || c.disconnectedMatch || a.document && 11 !== a.document.nodeType) return d
            } catch (e) {}
            return fa(b, n, null, [a]).length > 0
        }, fa.contains = function (a, b) {
            return (a.ownerDocument || a) !== n && m(a), t(a, b)
        }, fa.attr = function (a, b) {
            (a.ownerDocument || a) !== n && m(a);
            var e = d.attrHandle[b.toLowerCase()],
                f = e && D.call(d.attrHandle, b.toLowerCase()) ? e(a, b, !p) : void 0;
            return void 0 !== f ? f : c.attributes || !p ? a.getAttribute(b) : (f = a.getAttributeNode(b)) && f.specified ? f.value : null
        }, fa.error = function (a) {
            throw new Error("Syntax error, unrecognized expression: " + a)
        }, fa.uniqueSort = function (a) {
            var b, d = [],
                e = 0,
                f = 0;
            if (l = !c.detectDuplicates, k = !c.sortStable && a.slice(0), a.sort(B), l) {
                while (b = a[f++]) b === a[f] && (e = d.push(f));
                while (e--) a.splice(d[e], 1)
            }
            return k = null, a
        }, e = fa.getText = function (a) {
            var b, c = "",
                d = 0,
                f = a.nodeType;
            if (f) {
                if (1 === f || 9 === f || 11 === f) {
                    if ("string" == typeof a.textContent) return a.textContent;
                    for (a = a.firstChild; a; a = a.nextSibling) c += e(a)
                } else if (3 === f || 4 === f) return a.nodeValue
            } else
                while (b = a[d++]) c += e(b);
            return c
        }, d = fa.selectors = {
            cacheLength: 50,
            createPseudo: ha,
            match: W,
            attrHandle: {},
            find: {},
            relative: {
                ">": {
                    dir: "parentNode",
                    first: !0
                },
                " ": {
                    dir: "parentNode"
                },
                "+": {
                    dir: "previousSibling",
                    first: !0
                },
                "~": {
                    dir: "previousSibling"
                }
            },
            preFilter: {
                ATTR: function (a) {
                    return a[1] = a[1].replace(ba, ca), a[3] = (a[3] || a[4] || a[5] || "").replace(ba, ca), "~=" === a[2] && (a[3] = " " + a[3] + " "), a.slice(0, 4)
                },
                CHILD: function (a) {
                    return a[1] = a[1].toLowerCase(), "nth" === a[1].slice(0, 3) ? (a[3] || fa.error(a[0]), a[4] = +(a[4] ? a[5] + (a[6] || 1) : 2 * ("even" === a[3] || "odd" === a[3])), a[5] = +(a[7] + a[8] || "odd" === a[3])) : a[3] && fa.error(a[0]), a
                },
                PSEUDO: function (a) {
                    var b, c = !a[6] && a[2];
                    return W.CHILD.test(a[0]) ? null : (a[3] ? a[2] = a[4] || a[5] || "" : c && U.test(c) && (b = g(c, !0)) && (b = c.indexOf(")", c.length - b) - c.length) && (a[0] = a[0].slice(0, b), a[2] = c.slice(0, b)), a.slice(0, 3))
                }
            },
            filter: {
                TAG: function (a) {
                    var b = a.replace(ba, ca).toLowerCase();
                    return "*" === a ? function () {
                        return !0
                    } : function (a) {
                        return a.nodeName && a.nodeName.toLowerCase() === b
                    }
                },
                CLASS: function (a) {
                    var b = y[a + " "];
                    return b || (b = new RegExp("(^|" + L + ")" + a + "(" + L + "|$)")) && y(a, function (a) {
                        return b.test("string" == typeof a.className && a.className || "undefined" != typeof a.getAttribute && a.getAttribute("class") || "")
                    })
                },
                ATTR: function (a, b, c) {
                    return function (d) {
                        var e = fa.attr(d, a);
                        return null == e ? "!=" === b : b ? (e += "", "=" === b ? e === c : "!=" === b ? e !== c : "^=" === b ? c && 0 === e.indexOf(c) : "*=" === b ? c && e.indexOf(c) > -1 : "$=" === b ? c && e.slice(-c.length) === c : "~=" === b ? (" " + e.replace(P, " ") + " ").indexOf(c) > -1 : "|=" === b ? e === c || e.slice(0, c.length + 1) === c + "-" : !1) : !0
                    }
                },
                CHILD: function (a, b, c, d, e) {
                    var f = "nth" !== a.slice(0, 3),
                        g = "last" !== a.slice(-4),
                        h = "of-type" === b;
                    return 1 === d && 0 === e ? function (a) {
                        return !!a.parentNode
                    } : function (b, c, i) {
                        var j, k, l, m, n, o, p = f !== g ? "nextSibling" : "previousSibling",
                            q = b.parentNode,
                            r = h && b.nodeName.toLowerCase(),
                            s = !i && !h,
                            t = !1;
                        if (q) {
                            if (f) {
                                while (p) {
                                    m = b;
                                    while (m = m[p])
                                        if (h ? m.nodeName.toLowerCase() === r : 1 === m.nodeType) return !1;
                                    o = p = "only" === a && !o && "nextSibling"
                                }
                                return !0
                            }
                            if (o = [g ? q.firstChild : q.lastChild], g && s) {
                                m = q, l = m[u] || (m[u] = {}), k = l[m.uniqueID] || (l[m.uniqueID] = {}), j = k[a] || [], n = j[0] === w && j[1], t = n && j[2], m = n && q.childNodes[n];
                                while (m = ++n && m && m[p] || (t = n = 0) || o.pop())
                                    if (1 === m.nodeType && ++t && m === b) {
                                        k[a] = [w, n, t];
                                        break
                                    }
                            } else if (s && (m = b, l = m[u] || (m[u] = {}), k = l[m.uniqueID] || (l[m.uniqueID] = {}), j = k[a] || [], n = j[0] === w && j[1], t = n), t === !1)
                                while (m = ++n && m && m[p] || (t = n = 0) || o.pop())
                                    if ((h ? m.nodeName.toLowerCase() === r : 1 === m.nodeType) && ++t && (s && (l = m[u] || (m[u] = {}), k = l[m.uniqueID] || (l[m.uniqueID] = {}), k[a] = [w, t]), m === b)) break;
                            return t -= e, t === d || t % d === 0 && t / d >= 0
                        }
                    }
                },
                PSEUDO: function (a, b) {
                    var c, e = d.pseudos[a] || d.setFilters[a.toLowerCase()] || fa.error("unsupported pseudo: " + a);
                    return e[u] ? e(b) : e.length > 1 ? (c = [a, a, "", b], d.setFilters.hasOwnProperty(a.toLowerCase()) ? ha(function (a, c) {
                        var d, f = e(a, b),
                            g = f.length;
                        while (g--) d = J(a, f[g]), a[d] = !(c[d] = f[g])
                    }) : function (a) {
                        return e(a, 0, c)
                    }) : e
                }
            },
            pseudos: {
                not: ha(function (a) {
                    var b = [],
                        c = [],
                        d = h(a.replace(Q, "$1"));
                    return d[u] ? ha(function (a, b, c, e) {
                        var f, g = d(a, null, e, []),
                            h = a.length;
                        while (h--)(f = g[h]) && (a[h] = !(b[h] = f))
                    }) : function (a, e, f) {
                        return b[0] = a, d(b, null, f, c), b[0] = null, !c.pop()
                    }
                }),
                has: ha(function (a) {
                    return function (b) {
                        return fa(a, b).length > 0
                    }
                }),
                contains: ha(function (a) {
                    return a = a.replace(ba, ca),
                        function (b) {
                            return (b.textContent || b.innerText || e(b)).indexOf(a) > -1
                        }
                }),
                lang: ha(function (a) {
                    return V.test(a || "") || fa.error("unsupported lang: " + a), a = a.replace(ba, ca).toLowerCase(),
                        function (b) {
                            var c;
                            do
                                if (c = p ? b.lang : b.getAttribute("xml:lang") || b.getAttribute("lang")) return c = c.toLowerCase(), c === a || 0 === c.indexOf(a + "-"); while ((b = b.parentNode) && 1 === b.nodeType);
                            return !1
                        }
                }),
                target: function (b) {
                    var c = a.location && a.location.hash;
                    return c && c.slice(1) === b.id
                },
                root: function (a) {
                    return a === o
                },
                focus: function (a) {
                    return a === n.activeElement && (!n.hasFocus || n.hasFocus()) && !!(a.type || a.href || ~a.tabIndex)
                },
                enabled: function (a) {
                    return a.disabled === !1
                },
                disabled: function (a) {
                    return a.disabled === !0
                },
                checked: function (a) {
                    var b = a.nodeName.toLowerCase();
                    return "input" === b && !!a.checked || "option" === b && !!a.selected
                },
                selected: function (a) {
                    return a.parentNode && a.parentNode.selectedIndex, a.selected === !0
                },
                empty: function (a) {
                    for (a = a.firstChild; a; a = a.nextSibling)
                        if (a.nodeType < 6) return !1;
                    return !0
                },
                parent: function (a) {
                    return !d.pseudos.empty(a)
                },
                header: function (a) {
                    return Y.test(a.nodeName)
                },
                input: function (a) {
                    return X.test(a.nodeName)
                },
                button: function (a) {
                    var b = a.nodeName.toLowerCase();
                    return "input" === b && "button" === a.type || "button" === b
                },
                text: function (a) {
                    var b;
                    return "input" === a.nodeName.toLowerCase() && "text" === a.type && (null == (b = a.getAttribute("type")) || "text" === b.toLowerCase())
                },
                first: na(function () {
                    return [0]
                }),
                last: na(function (a, b) {
                    return [b - 1]
                }),
                eq: na(function (a, b, c) {
                    return [0 > c ? c + b : c]
                }),
                even: na(function (a, b) {
                    for (var c = 0; b > c; c += 2) a.push(c);
                    return a
                }),
                odd: na(function (a, b) {
                    for (var c = 1; b > c; c += 2) a.push(c);
                    return a
                }),
                lt: na(function (a, b, c) {
                    for (var d = 0 > c ? c + b : c; --d >= 0;) a.push(d);
                    return a
                }),
                gt: na(function (a, b, c) {
                    for (var d = 0 > c ? c + b : c; ++d < b;) a.push(d);
                    return a
                })
            }
        }, d.pseudos.nth = d.pseudos.eq;
        for (b in {
                radio: !0,
                checkbox: !0,
                file: !0,
                password: !0,
                image: !0
            }) d.pseudos[b] = la(b);
        for (b in {
                submit: !0,
                reset: !0
            }) d.pseudos[b] = ma(b);

        function pa() {}
        pa.prototype = d.filters = d.pseudos, d.setFilters = new pa, g = fa.tokenize = function (a, b) {
            var c, e, f, g, h, i, j, k = z[a + " "];
            if (k) return b ? 0 : k.slice(0);
            h = a, i = [], j = d.preFilter;
            while (h) {
                c && !(e = R.exec(h)) || (e && (h = h.slice(e[0].length) || h), i.push(f = [])), c = !1, (e = S.exec(h)) && (c = e.shift(), f.push({
                    value: c,
                    type: e[0].replace(Q, " ")
                }), h = h.slice(c.length));
                for (g in d.filter) !(e = W[g].exec(h)) || j[g] && !(e = j[g](e)) || (c = e.shift(), f.push({
                    value: c,
                    type: g,
                    matches: e
                }), h = h.slice(c.length));
                if (!c) break
            }
            return b ? h.length : h ? fa.error(a) : z(a, i).slice(0)
        };

        function qa(a) {
            for (var b = 0, c = a.length, d = ""; c > b; b++) d += a[b].value;
            return d
        }

        function ra(a, b, c) {
            var d = b.dir,
                e = c && "parentNode" === d,
                f = x++;
            return b.first ? function (b, c, f) {
                while (b = b[d])
                    if (1 === b.nodeType || e) return a(b, c, f)
            } : function (b, c, g) {
                var h, i, j, k = [w, f];
                if (g) {
                    while (b = b[d])
                        if ((1 === b.nodeType || e) && a(b, c, g)) return !0
                } else
                    while (b = b[d])
                        if (1 === b.nodeType || e) {
                            if (j = b[u] || (b[u] = {}), i = j[b.uniqueID] || (j[b.uniqueID] = {}), (h = i[d]) && h[0] === w && h[1] === f) return k[2] = h[2];
                            if (i[d] = k, k[2] = a(b, c, g)) return !0
                        }
            }
        }

        function sa(a) {
            return a.length > 1 ? function (b, c, d) {
                var e = a.length;
                while (e--)
                    if (!a[e](b, c, d)) return !1;
                return !0
            } : a[0]
        }

        function ta(a, b, c) {
            for (var d = 0, e = b.length; e > d; d++) fa(a, b[d], c);
            return c
        }

        function ua(a, b, c, d, e) {
            for (var f, g = [], h = 0, i = a.length, j = null != b; i > h; h++)(f = a[h]) && (c && !c(f, d, e) || (g.push(f), j && b.push(h)));
            return g
        }

        function va(a, b, c, d, e, f) {
            return d && !d[u] && (d = va(d)), e && !e[u] && (e = va(e, f)), ha(function (f, g, h, i) {
                var j, k, l, m = [],
                    n = [],
                    o = g.length,
                    p = f || ta(b || "*", h.nodeType ? [h] : h, []),
                    q = !a || !f && b ? p : ua(p, m, a, h, i),
                    r = c ? e || (f ? a : o || d) ? [] : g : q;
                if (c && c(q, r, h, i), d) {
                    j = ua(r, n), d(j, [], h, i), k = j.length;
                    while (k--)(l = j[k]) && (r[n[k]] = !(q[n[k]] = l))
                }
                if (f) {
                    if (e || a) {
                        if (e) {
                            j = [], k = r.length;
                            while (k--)(l = r[k]) && j.push(q[k] = l);
                            e(null, r = [], j, i)
                        }
                        k = r.length;
                        while (k--)(l = r[k]) && (j = e ? J(f, l) : m[k]) > -1 && (f[j] = !(g[j] = l))
                    }
                } else r = ua(r === g ? r.splice(o, r.length) : r), e ? e(null, g, r, i) : H.apply(g, r)
            })
        }

        function wa(a) {
            for (var b, c, e, f = a.length, g = d.relative[a[0].type], h = g || d.relative[" "], i = g ? 1 : 0, k = ra(function (a) {
                    return a === b
                }, h, !0), l = ra(function (a) {
                    return J(b, a) > -1
                }, h, !0), m = [function (a, c, d) {
                    var e = !g && (d || c !== j) || ((b = c).nodeType ? k(a, c, d) : l(a, c, d));
                    return b = null, e
                }]; f > i; i++)
                if (c = d.relative[a[i].type]) m = [ra(sa(m), c)];
                else {
                    if (c = d.filter[a[i].type].apply(null, a[i].matches), c[u]) {
                        for (e = ++i; f > e; e++)
                            if (d.relative[a[e].type]) break;
                        return va(i > 1 && sa(m), i > 1 && qa(a.slice(0, i - 1).concat({
                            value: " " === a[i - 2].type ? "*" : ""
                        })).replace(Q, "$1"), c, e > i && wa(a.slice(i, e)), f > e && wa(a = a.slice(e)), f > e && qa(a))
                    }
                    m.push(c)
                } return sa(m)
        }

        function xa(a, b) {
            var c = b.length > 0,
                e = a.length > 0,
                f = function (f, g, h, i, k) {
                    var l, o, q, r = 0,
                        s = "0",
                        t = f && [],
                        u = [],
                        v = j,
                        x = f || e && d.find.TAG("*", k),
                        y = w += null == v ? 1 : Math.random() || .1,
                        z = x.length;
                    for (k && (j = g === n || g || k); s !== z && null != (l = x[s]); s++) {
                        if (e && l) {
                            o = 0, g || l.ownerDocument === n || (m(l), h = !p);
                            while (q = a[o++])
                                if (q(l, g || n, h)) {
                                    i.push(l);
                                    break
                                } k && (w = y)
                        }
                        c && ((l = !q && l) && r--, f && t.push(l))
                    }
                    if (r += s, c && s !== r) {
                        o = 0;
                        while (q = b[o++]) q(t, u, g, h);
                        if (f) {
                            if (r > 0)
                                while (s--) t[s] || u[s] || (u[s] = F.call(i));
                            u = ua(u)
                        }
                        H.apply(i, u), k && !f && u.length > 0 && r + b.length > 1 && fa.uniqueSort(i)
                    }
                    return k && (w = y, j = v), t
                };
            return c ? ha(f) : f
        }
        return h = fa.compile = function (a, b) {
            var c, d = [],
                e = [],
                f = A[a + " "];
            if (!f) {
                b || (b = g(a)), c = b.length;
                while (c--) f = wa(b[c]), f[u] ? d.push(f) : e.push(f);
                f = A(a, xa(e, d)), f.selector = a
            }
            return f
        }, i = fa.select = function (a, b, e, f) {
            var i, j, k, l, m, n = "function" == typeof a && a,
                o = !f && g(a = n.selector || a);
            if (e = e || [], 1 === o.length) {
                if (j = o[0] = o[0].slice(0), j.length > 2 && "ID" === (k = j[0]).type && c.getById && 9 === b.nodeType && p && d.relative[j[1].type]) {
                    if (b = (d.find.ID(k.matches[0].replace(ba, ca), b) || [])[0], !b) return e;
                    n && (b = b.parentNode), a = a.slice(j.shift().value.length)
                }
                i = W.needsContext.test(a) ? 0 : j.length;
                while (i--) {
                    if (k = j[i], d.relative[l = k.type]) break;
                    if ((m = d.find[l]) && (f = m(k.matches[0].replace(ba, ca), _.test(j[0].type) && oa(b.parentNode) || b))) {
                        if (j.splice(i, 1), a = f.length && qa(j), !a) return H.apply(e, f), e;
                        break
                    }
                }
            }
            return (n || h(a, o))(f, b, !p, e, !b || _.test(a) && oa(b.parentNode) || b), e
        }, c.sortStable = u.split("").sort(B).join("") === u, c.detectDuplicates = !!l, m(), c.sortDetached = ia(function (a) {
            return 1 & a.compareDocumentPosition(n.createElement("div"))
        }), ia(function (a) {
            return a.innerHTML = "<a href='#'></a>", "#" === a.firstChild.getAttribute("href")
        }) || ja("type|href|height|width", function (a, b, c) {
            return c ? void 0 : a.getAttribute(b, "type" === b.toLowerCase() ? 1 : 2)
        }), c.attributes && ia(function (a) {
            return a.innerHTML = "<input/>", a.firstChild.setAttribute("value", ""), "" === a.firstChild.getAttribute("value")
        }) || ja("value", function (a, b, c) {
            return c || "input" !== a.nodeName.toLowerCase() ? void 0 : a.defaultValue
        }), ia(function (a) {
            return null == a.getAttribute("disabled")
        }) || ja(K, function (a, b, c) {
            var d;
            return c ? void 0 : a[b] === !0 ? b.toLowerCase() : (d = a.getAttributeNode(b)) && d.specified ? d.value : null
        }), fa
    }(a);
    n.find = t, n.expr = t.selectors, n.expr[":"] = n.expr.pseudos, n.uniqueSort = n.unique = t.uniqueSort, n.text = t.getText, n.isXMLDoc = t.isXML, n.contains = t.contains;
    var u = function (a, b, c) {
            var d = [],
                e = void 0 !== c;
            while ((a = a[b]) && 9 !== a.nodeType)
                if (1 === a.nodeType) {
                    if (e && n(a).is(c)) break;
                    d.push(a)
                } return d
        },
        v = function (a, b) {
            for (var c = []; a; a = a.nextSibling) 1 === a.nodeType && a !== b && c.push(a);
            return c
        },
        w = n.expr.match.needsContext,
        x = /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,
        y = /^.[^:#\[\.,]*$/;

    function z(a, b, c) {
        if (n.isFunction(b)) return n.grep(a, function (a, d) {
            return !!b.call(a, d, a) !== c
        });
        if (b.nodeType) return n.grep(a, function (a) {
            return a === b !== c
        });
        if ("string" == typeof b) {
            if (y.test(b)) return n.filter(b, a, c);
            b = n.filter(b, a)
        }
        return n.grep(a, function (a) {
            return h.call(b, a) > -1 !== c
        })
    }
    n.filter = function (a, b, c) {
        var d = b[0];
        return c && (a = ":not(" + a + ")"), 1 === b.length && 1 === d.nodeType ? n.find.matchesSelector(d, a) ? [d] : [] : n.find.matches(a, n.grep(b, function (a) {
            return 1 === a.nodeType
        }))
    }, n.fn.extend({
        find: function (a) {
            var b, c = this.length,
                d = [],
                e = this;
            if ("string" != typeof a) return this.pushStack(n(a).filter(function () {
                for (b = 0; c > b; b++)
                    if (n.contains(e[b], this)) return !0
            }));
            for (b = 0; c > b; b++) n.find(a, e[b], d);
            return d = this.pushStack(c > 1 ? n.unique(d) : d), d.selector = this.selector ? this.selector + " " + a : a, d
        },
        filter: function (a) {
            return this.pushStack(z(this, a || [], !1))
        },
        not: function (a) {
            return this.pushStack(z(this, a || [], !0))
        },
        is: function (a) {
            return !!z(this, "string" == typeof a && w.test(a) ? n(a) : a || [], !1).length
        }
    });
    var A, B = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
        C = n.fn.init = function (a, b, c) {
            var e, f;
            if (!a) return this;
            if (c = c || A, "string" == typeof a) {
                if (e = "<" === a[0] && ">" === a[a.length - 1] && a.length >= 3 ? [null, a, null] : B.exec(a), !e || !e[1] && b) return !b || b.jquery ? (b || c).find(a) : this.constructor(b).find(a);
                if (e[1]) {
                    if (b = b instanceof n ? b[0] : b, n.merge(this, n.parseHTML(e[1], b && b.nodeType ? b.ownerDocument || b : d, !0)), x.test(e[1]) && n.isPlainObject(b))
                        for (e in b) n.isFunction(this[e]) ? this[e](b[e]) : this.attr(e, b[e]);
                    return this
                }
                return f = d.getElementById(e[2]), f && f.parentNode && (this.length = 1, this[0] = f), this.context = d, this.selector = a, this
            }
            return a.nodeType ? (this.context = this[0] = a, this.length = 1, this) : n.isFunction(a) ? void 0 !== c.ready ? c.ready(a) : a(n) : (void 0 !== a.selector && (this.selector = a.selector, this.context = a.context), n.makeArray(a, this))
        };
    C.prototype = n.fn, A = n(d);
    var D = /^(?:parents|prev(?:Until|All))/,
        E = {
            children: !0,
            contents: !0,
            next: !0,
            prev: !0
        };
    n.fn.extend({
        has: function (a) {
            var b = n(a, this),
                c = b.length;
            return this.filter(function () {
                for (var a = 0; c > a; a++)
                    if (n.contains(this, b[a])) return !0
            })
        },
        closest: function (a, b) {
            for (var c, d = 0, e = this.length, f = [], g = w.test(a) || "string" != typeof a ? n(a, b || this.context) : 0; e > d; d++)
                for (c = this[d]; c && c !== b; c = c.parentNode)
                    if (c.nodeType < 11 && (g ? g.index(c) > -1 : 1 === c.nodeType && n.find.matchesSelector(c, a))) {
                        f.push(c);
                        break
                    } return this.pushStack(f.length > 1 ? n.uniqueSort(f) : f)
        },
        index: function (a) {
            return a ? "string" == typeof a ? h.call(n(a), this[0]) : h.call(this, a.jquery ? a[0] : a) : this[0] && this[0].parentNode ? this.first().prevAll().length : -1
        },
        add: function (a, b) {
            return this.pushStack(n.uniqueSort(n.merge(this.get(), n(a, b))))
        },
        addBack: function (a) {
            return this.add(null == a ? this.prevObject : this.prevObject.filter(a))
        }
    });

    function F(a, b) {
        while ((a = a[b]) && 1 !== a.nodeType);
        return a
    }
    n.each({
        parent: function (a) {
            var b = a.parentNode;
            return b && 11 !== b.nodeType ? b : null
        },
        parents: function (a) {
            return u(a, "parentNode")
        },
        parentsUntil: function (a, b, c) {
            return u(a, "parentNode", c)
        },
        next: function (a) {
            return F(a, "nextSibling")
        },
        prev: function (a) {
            return F(a, "previousSibling")
        },
        nextAll: function (a) {
            return u(a, "nextSibling")
        },
        prevAll: function (a) {
            return u(a, "previousSibling")
        },
        nextUntil: function (a, b, c) {
            return u(a, "nextSibling", c)
        },
        prevUntil: function (a, b, c) {
            return u(a, "previousSibling", c)
        },
        siblings: function (a) {
            return v((a.parentNode || {}).firstChild, a)
        },
        children: function (a) {
            return v(a.firstChild)
        },
        contents: function (a) {
            return a.contentDocument || n.merge([], a.childNodes)
        }
    }, function (a, b) {
        n.fn[a] = function (c, d) {
            var e = n.map(this, b, c);
            return "Until" !== a.slice(-5) && (d = c), d && "string" == typeof d && (e = n.filter(d, e)), this.length > 1 && (E[a] || n.uniqueSort(e), D.test(a) && e.reverse()), this.pushStack(e)
        }
    });
    var G = /\S+/g;

    function H(a) {
        var b = {};
        return n.each(a.match(G) || [], function (a, c) {
            b[c] = !0
        }), b
    }
    n.Callbacks = function (a) {
        a = "string" == typeof a ? H(a) : n.extend({}, a);
        var b, c, d, e, f = [],
            g = [],
            h = -1,
            i = function () {
                for (e = a.once, d = b = !0; g.length; h = -1) {
                    c = g.shift();
                    while (++h < f.length) f[h].apply(c[0], c[1]) === !1 && a.stopOnFalse && (h = f.length, c = !1)
                }
                a.memory || (c = !1), b = !1, e && (f = c ? [] : "")
            },
            j = {
                add: function () {
                    return f && (c && !b && (h = f.length - 1, g.push(c)), function d(b) {
                        n.each(b, function (b, c) {
                            n.isFunction(c) ? a.unique && j.has(c) || f.push(c) : c && c.length && "string" !== n.type(c) && d(c)
                        })
                    }(arguments), c && !b && i()), this
                },
                remove: function () {
                    return n.each(arguments, function (a, b) {
                        var c;
                        while ((c = n.inArray(b, f, c)) > -1) f.splice(c, 1), h >= c && h--
                    }), this
                },
                has: function (a) {
                    return a ? n.inArray(a, f) > -1 : f.length > 0
                },
                empty: function () {
                    return f && (f = []), this
                },
                disable: function () {
                    return e = g = [], f = c = "", this
                },
                disabled: function () {
                    return !f
                },
                lock: function () {
                    return e = g = [], c || (f = c = ""), this
                },
                locked: function () {
                    return !!e
                },
                fireWith: function (a, c) {
                    return e || (c = c || [], c = [a, c.slice ? c.slice() : c], g.push(c), b || i()), this
                },
                fire: function () {
                    return j.fireWith(this, arguments), this
                },
                fired: function () {
                    return !!d
                }
            };
        return j
    }, n.extend({
        Deferred: function (a) {
            var b = [
                    ["resolve", "done", n.Callbacks("once memory"), "resolved"],
                    ["reject", "fail", n.Callbacks("once memory"), "rejected"],
                    ["notify", "progress", n.Callbacks("memory")]
                ],
                c = "pending",
                d = {
                    state: function () {
                        return c
                    },
                    always: function () {
                        return e.done(arguments).fail(arguments), this
                    },
                    then: function () {
                        var a = arguments;
                        return n.Deferred(function (c) {
                            n.each(b, function (b, f) {
                                var g = n.isFunction(a[b]) && a[b];
                                e[f[1]](function () {
                                    var a = g && g.apply(this, arguments);
                                    a && n.isFunction(a.promise) ? a.promise().progress(c.notify).done(c.resolve).fail(c.reject) : c[f[0] + "With"](this === d ? c.promise() : this, g ? [a] : arguments)
                                })
                            }), a = null
                        }).promise()
                    },
                    promise: function (a) {
                        return null != a ? n.extend(a, d) : d
                    }
                },
                e = {};
            return d.pipe = d.then, n.each(b, function (a, f) {
                var g = f[2],
                    h = f[3];
                d[f[1]] = g.add, h && g.add(function () {
                    c = h
                }, b[1 ^ a][2].disable, b[2][2].lock), e[f[0]] = function () {
                    return e[f[0] + "With"](this === e ? d : this, arguments), this
                }, e[f[0] + "With"] = g.fireWith
            }), d.promise(e), a && a.call(e, e), e
        },
        when: function (a) {
            var b = 0,
                c = e.call(arguments),
                d = c.length,
                f = 1 !== d || a && n.isFunction(a.promise) ? d : 0,
                g = 1 === f ? a : n.Deferred(),
                h = function (a, b, c) {
                    return function (d) {
                        b[a] = this, c[a] = arguments.length > 1 ? e.call(arguments) : d, c === i ? g.notifyWith(b, c) : --f || g.resolveWith(b, c)
                    }
                },
                i, j, k;
            if (d > 1)
                for (i = new Array(d), j = new Array(d), k = new Array(d); d > b; b++) c[b] && n.isFunction(c[b].promise) ? c[b].promise().progress(h(b, j, i)).done(h(b, k, c)).fail(g.reject) : --f;
            return f || g.resolveWith(k, c), g.promise()
        }
    });
    var I;
    n.fn.ready = function (a) {
        return n.ready.promise().done(a), this
    }, n.extend({
        isReady: !1,
        readyWait: 1,
        holdReady: function (a) {
            a ? n.readyWait++ : n.ready(!0)
        },
        ready: function (a) {
            (a === !0 ? --n.readyWait : n.isReady) || (n.isReady = !0, a !== !0 && --n.readyWait > 0 || (I.resolveWith(d, [n]), n.fn.triggerHandler && (n(d).triggerHandler("ready"), n(d).off("ready"))))
        }
    });

    function J() {
        d.removeEventListener("DOMContentLoaded", J), a.removeEventListener("load", J), n.ready()
    }
    n.ready.promise = function (b) {
        return I || (I = n.Deferred(), "complete" === d.readyState || "loading" !== d.readyState && !d.documentElement.doScroll ? a.setTimeout(n.ready) : (d.addEventListener("DOMContentLoaded", J), a.addEventListener("load", J))), I.promise(b)
    }, n.ready.promise();
    var K = function (a, b, c, d, e, f, g) {
            var h = 0,
                i = a.length,
                j = null == c;
            if ("object" === n.type(c)) {
                e = !0;
                for (h in c) K(a, b, h, c[h], !0, f, g)
            } else if (void 0 !== d && (e = !0, n.isFunction(d) || (g = !0), j && (g ? (b.call(a, d), b = null) : (j = b, b = function (a, b, c) {
                    return j.call(n(a), c)
                })), b))
                for (; i > h; h++) b(a[h], c, g ? d : d.call(a[h], h, b(a[h], c)));
            return e ? a : j ? b.call(a) : i ? b(a[0], c) : f
        },
        L = function (a) {
            return 1 === a.nodeType || 9 === a.nodeType || !+a.nodeType
        };

    function M() {
        this.expando = n.expando + M.uid++
    }
    M.uid = 1, M.prototype = {
        register: function (a, b) {
            var c = b || {};
            return a.nodeType ? a[this.expando] = c : Object.defineProperty(a, this.expando, {
                value: c,
                writable: !0,
                configurable: !0
            }), a[this.expando]
        },
        cache: function (a) {
            if (!L(a)) return {};
            var b = a[this.expando];
            return b || (b = {}, L(a) && (a.nodeType ? a[this.expando] = b : Object.defineProperty(a, this.expando, {
                value: b,
                configurable: !0
            }))), b
        },
        set: function (a, b, c) {
            var d, e = this.cache(a);
            if ("string" == typeof b) e[b] = c;
            else
                for (d in b) e[d] = b[d];
            return e
        },
        get: function (a, b) {
            return void 0 === b ? this.cache(a) : a[this.expando] && a[this.expando][b]
        },
        access: function (a, b, c) {
            var d;
            return void 0 === b || b && "string" == typeof b && void 0 === c ? (d = this.get(a, b), void 0 !== d ? d : this.get(a, n.camelCase(b))) : (this.set(a, b, c), void 0 !== c ? c : b)
        },
        remove: function (a, b) {
            var c, d, e, f = a[this.expando];
            if (void 0 !== f) {
                if (void 0 === b) this.register(a);
                else {
                    n.isArray(b) ? d = b.concat(b.map(n.camelCase)) : (e = n.camelCase(b), b in f ? d = [b, e] : (d = e, d = d in f ? [d] : d.match(G) || [])), c = d.length;
                    while (c--) delete f[d[c]]
                }(void 0 === b || n.isEmptyObject(f)) && (a.nodeType ? a[this.expando] = void 0 : delete a[this.expando])
            }
        },
        hasData: function (a) {
            var b = a[this.expando];
            return void 0 !== b && !n.isEmptyObject(b)
        }
    };
    var N = new M,
        O = new M,
        P = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
        Q = /[A-Z]/g;

    function R(a, b, c) {
        var d;
        if (void 0 === c && 1 === a.nodeType)
            if (d = "data-" + b.replace(Q, "-$&").toLowerCase(), c = a.getAttribute(d), "string" == typeof c) {
                try {
                    c = "true" === c ? !0 : "false" === c ? !1 : "null" === c ? null : +c + "" === c ? +c : P.test(c) ? n.parseJSON(c) : c;
                } catch (e) {}
                O.set(a, b, c)
            } else c = void 0;
        return c
    }
    n.extend({
        hasData: function (a) {
            return O.hasData(a) || N.hasData(a)
        },
        data: function (a, b, c) {
            return O.access(a, b, c)
        },
        removeData: function (a, b) {
            O.remove(a, b)
        },
        _data: function (a, b, c) {
            return N.access(a, b, c)
        },
        _removeData: function (a, b) {
            N.remove(a, b)
        }
    }), n.fn.extend({
        data: function (a, b) {
            var c, d, e, f = this[0],
                g = f && f.attributes;
            if (void 0 === a) {
                if (this.length && (e = O.get(f), 1 === f.nodeType && !N.get(f, "hasDataAttrs"))) {
                    c = g.length;
                    while (c--) g[c] && (d = g[c].name, 0 === d.indexOf("data-") && (d = n.camelCase(d.slice(5)), R(f, d, e[d])));
                    N.set(f, "hasDataAttrs", !0)
                }
                return e
            }
            return "object" == typeof a ? this.each(function () {
                O.set(this, a)
            }) : K(this, function (b) {
                var c, d;
                if (f && void 0 === b) {
                    if (c = O.get(f, a) || O.get(f, a.replace(Q, "-$&").toLowerCase()), void 0 !== c) return c;
                    if (d = n.camelCase(a), c = O.get(f, d), void 0 !== c) return c;
                    if (c = R(f, d, void 0), void 0 !== c) return c
                } else d = n.camelCase(a), this.each(function () {
                    var c = O.get(this, d);
                    O.set(this, d, b), a.indexOf("-") > -1 && void 0 !== c && O.set(this, a, b)
                })
            }, null, b, arguments.length > 1, null, !0)
        },
        removeData: function (a) {
            return this.each(function () {
                O.remove(this, a)
            })
        }
    }), n.extend({
        queue: function (a, b, c) {
            var d;
            return a ? (b = (b || "fx") + "queue", d = N.get(a, b), c && (!d || n.isArray(c) ? d = N.access(a, b, n.makeArray(c)) : d.push(c)), d || []) : void 0
        },
        dequeue: function (a, b) {
            b = b || "fx";
            var c = n.queue(a, b),
                d = c.length,
                e = c.shift(),
                f = n._queueHooks(a, b),
                g = function () {
                    n.dequeue(a, b)
                };
            "inprogress" === e && (e = c.shift(), d--), e && ("fx" === b && c.unshift("inprogress"), delete f.stop, e.call(a, g, f)), !d && f && f.empty.fire()
        },
        _queueHooks: function (a, b) {
            var c = b + "queueHooks";
            return N.get(a, c) || N.access(a, c, {
                empty: n.Callbacks("once memory").add(function () {
                    N.remove(a, [b + "queue", c])
                })
            })
        }
    }), n.fn.extend({
        queue: function (a, b) {
            var c = 2;
            return "string" != typeof a && (b = a, a = "fx", c--), arguments.length < c ? n.queue(this[0], a) : void 0 === b ? this : this.each(function () {
                var c = n.queue(this, a, b);
                n._queueHooks(this, a), "fx" === a && "inprogress" !== c[0] && n.dequeue(this, a)
            })
        },
        dequeue: function (a) {
            return this.each(function () {
                n.dequeue(this, a)
            })
        },
        clearQueue: function (a) {
            return this.queue(a || "fx", [])
        },
        promise: function (a, b) {
            var c, d = 1,
                e = n.Deferred(),
                f = this,
                g = this.length,
                h = function () {
                    --d || e.resolveWith(f, [f])
                };
            "string" != typeof a && (b = a, a = void 0), a = a || "fx";
            while (g--) c = N.get(f[g], a + "queueHooks"), c && c.empty && (d++, c.empty.add(h));
            return h(), e.promise(b)
        }
    });
    var S = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,
        T = new RegExp("^(?:([+-])=|)(" + S + ")([a-z%]*)$", "i"),
        U = ["Top", "Right", "Bottom", "Left"],
        V = function (a, b) {
            return a = b || a, "none" === n.css(a, "display") || !n.contains(a.ownerDocument, a)
        };

    function W(a, b, c, d) {
        var e, f = 1,
            g = 20,
            h = d ? function () {
                return d.cur()
            } : function () {
                return n.css(a, b, "")
            },
            i = h(),
            j = c && c[3] || (n.cssNumber[b] ? "" : "px"),
            k = (n.cssNumber[b] || "px" !== j && +i) && T.exec(n.css(a, b));
        if (k && k[3] !== j) {
            j = j || k[3], c = c || [], k = +i || 1;
            do f = f || ".5", k /= f, n.style(a, b, k + j); while (f !== (f = h() / i) && 1 !== f && --g)
        }
        return c && (k = +k || +i || 0, e = c[1] ? k + (c[1] + 1) * c[2] : +c[2], d && (d.unit = j, d.start = k, d.end = e)), e
    }
    var X = /^(?:checkbox|radio)$/i,
        Y = /<([\w:-]+)/,
        Z = /^$|\/(?:java|ecma)script/i,
        $ = {
            option: [1, "<select multiple='multiple'>", "</select>"],
            thead: [1, "<table>", "</table>"],
            col: [2, "<table><colgroup>", "</colgroup></table>"],
            tr: [2, "<table><tbody>", "</tbody></table>"],
            td: [3, "<table><tbody><tr>", "</tr></tbody></table>"],
            _default: [0, "", ""]
        };
    $.optgroup = $.option, $.tbody = $.tfoot = $.colgroup = $.caption = $.thead, $.th = $.td;

    function _(a, b) {
        var c = "undefined" != typeof a.getElementsByTagName ? a.getElementsByTagName(b || "*") : "undefined" != typeof a.querySelectorAll ? a.querySelectorAll(b || "*") : [];
        return void 0 === b || b && n.nodeName(a, b) ? n.merge([a], c) : c
    }

    function aa(a, b) {
        for (var c = 0, d = a.length; d > c; c++) N.set(a[c], "globalEval", !b || N.get(b[c], "globalEval"))
    }
    var ba = /<|&#?\w+;/;

    function ca(a, b, c, d, e) {
        for (var f, g, h, i, j, k, l = b.createDocumentFragment(), m = [], o = 0, p = a.length; p > o; o++)
            if (f = a[o], f || 0 === f)
                if ("object" === n.type(f)) n.merge(m, f.nodeType ? [f] : f);
                else if (ba.test(f)) {
            g = g || l.appendChild(b.createElement("div")), h = (Y.exec(f) || ["", ""])[1].toLowerCase(), i = $[h] || $._default, g.innerHTML = i[1] + n.htmlPrefilter(f) + i[2], k = i[0];
            while (k--) g = g.lastChild;
            n.merge(m, g.childNodes), g = l.firstChild, g.textContent = ""
        } else m.push(b.createTextNode(f));
        l.textContent = "", o = 0;
        while (f = m[o++])
            if (d && n.inArray(f, d) > -1) e && e.push(f);
            else if (j = n.contains(f.ownerDocument, f), g = _(l.appendChild(f), "script"), j && aa(g), c) {
            k = 0;
            while (f = g[k++]) Z.test(f.type || "") && c.push(f)
        }
        return l
    }! function () {
        var a = d.createDocumentFragment(),
            b = a.appendChild(d.createElement("div")),
            c = d.createElement("input");
        c.setAttribute("type", "radio"), c.setAttribute("checked", "checked"), c.setAttribute("name", "t"), b.appendChild(c), l.checkClone = b.cloneNode(!0).cloneNode(!0).lastChild.checked, b.innerHTML = "<textarea>x</textarea>", l.noCloneChecked = !!b.cloneNode(!0).lastChild.defaultValue
    }();
    var da = /^key/,
        ea = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
        fa = /^([^.]*)(?:\.(.+)|)/;

    function ga() {
        return !0
    }

    function ha() {
        return !1
    }

    function ia() {
        try {
            return d.activeElement
        } catch (a) {}
    }

    function ja(a, b, c, d, e, f) {
        var g, h;
        if ("object" == typeof b) {
            "string" != typeof c && (d = d || c, c = void 0);
            for (h in b) ja(a, h, c, d, b[h], f);
            return a
        }
        if (null == d && null == e ? (e = c, d = c = void 0) : null == e && ("string" == typeof c ? (e = d, d = void 0) : (e = d, d = c, c = void 0)), e === !1) e = ha;
        else if (!e) return a;
        return 1 === f && (g = e, e = function (a) {
            return n().off(a), g.apply(this, arguments)
        }, e.guid = g.guid || (g.guid = n.guid++)), a.each(function () {
            n.event.add(this, b, e, d, c)
        })
    }
    n.event = {
        global: {},
        add: function (a, b, c, d, e) {
            var f, g, h, i, j, k, l, m, o, p, q, r = N.get(a);
            if (r) {
                c.handler && (f = c, c = f.handler, e = f.selector), c.guid || (c.guid = n.guid++), (i = r.events) || (i = r.events = {}), (g = r.handle) || (g = r.handle = function (b) {
                    return "undefined" != typeof n && n.event.triggered !== b.type ? n.event.dispatch.apply(a, arguments) : void 0
                }), b = (b || "").match(G) || [""], j = b.length;
                while (j--) h = fa.exec(b[j]) || [], o = q = h[1], p = (h[2] || "").split(".").sort(), o && (l = n.event.special[o] || {}, o = (e ? l.delegateType : l.bindType) || o, l = n.event.special[o] || {}, k = n.extend({
                    type: o,
                    origType: q,
                    data: d,
                    handler: c,
                    guid: c.guid,
                    selector: e,
                    needsContext: e && n.expr.match.needsContext.test(e),
                    namespace: p.join(".")
                }, f), (m = i[o]) || (m = i[o] = [], m.delegateCount = 0, l.setup && l.setup.call(a, d, p, g) !== !1 || a.addEventListener && a.addEventListener(o, g)), l.add && (l.add.call(a, k), k.handler.guid || (k.handler.guid = c.guid)), e ? m.splice(m.delegateCount++, 0, k) : m.push(k), n.event.global[o] = !0)
            }
        },
        remove: function (a, b, c, d, e) {
            var f, g, h, i, j, k, l, m, o, p, q, r = N.hasData(a) && N.get(a);
            if (r && (i = r.events)) {
                b = (b || "").match(G) || [""], j = b.length;
                while (j--)
                    if (h = fa.exec(b[j]) || [], o = q = h[1], p = (h[2] || "").split(".").sort(), o) {
                        l = n.event.special[o] || {}, o = (d ? l.delegateType : l.bindType) || o, m = i[o] || [], h = h[2] && new RegExp("(^|\\.)" + p.join("\\.(?:.*\\.|)") + "(\\.|$)"), g = f = m.length;
                        while (f--) k = m[f], !e && q !== k.origType || c && c.guid !== k.guid || h && !h.test(k.namespace) || d && d !== k.selector && ("**" !== d || !k.selector) || (m.splice(f, 1), k.selector && m.delegateCount--, l.remove && l.remove.call(a, k));
                        g && !m.length && (l.teardown && l.teardown.call(a, p, r.handle) !== !1 || n.removeEvent(a, o, r.handle), delete i[o])
                    } else
                        for (o in i) n.event.remove(a, o + b[j], c, d, !0);
                n.isEmptyObject(i) && N.remove(a, "handle events")
            }
        },
        dispatch: function (a) {
            a = n.event.fix(a);
            var b, c, d, f, g, h = [],
                i = e.call(arguments),
                j = (N.get(this, "events") || {})[a.type] || [],
                k = n.event.special[a.type] || {};
            if (i[0] = a, a.delegateTarget = this, !k.preDispatch || k.preDispatch.call(this, a) !== !1) {
                h = n.event.handlers.call(this, a, j), b = 0;
                while ((f = h[b++]) && !a.isPropagationStopped()) {
                    a.currentTarget = f.elem, c = 0;
                    while ((g = f.handlers[c++]) && !a.isImmediatePropagationStopped()) a.rnamespace && !a.rnamespace.test(g.namespace) || (a.handleObj = g, a.data = g.data, d = ((n.event.special[g.origType] || {}).handle || g.handler).apply(f.elem, i), void 0 !== d && (a.result = d) === !1 && (a.preventDefault(), a.stopPropagation()))
                }
                return k.postDispatch && k.postDispatch.call(this, a), a.result
            }
        },
        handlers: function (a, b) {
            var c, d, e, f, g = [],
                h = b.delegateCount,
                i = a.target;
            if (h && i.nodeType && ("click" !== a.type || isNaN(a.button) || a.button < 1))
                for (; i !== this; i = i.parentNode || this)
                    if (1 === i.nodeType && (i.disabled !== !0 || "click" !== a.type)) {
                        for (d = [], c = 0; h > c; c++) f = b[c], e = f.selector + " ", void 0 === d[e] && (d[e] = f.needsContext ? n(e, this).index(i) > -1 : n.find(e, this, null, [i]).length), d[e] && d.push(f);
                        d.length && g.push({
                            elem: i,
                            handlers: d
                        })
                    } return h < b.length && g.push({
                elem: this,
                handlers: b.slice(h)
            }), g
        },
        props: "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
        fixHooks: {},
        keyHooks: {
            props: "char charCode key keyCode".split(" "),
            filter: function (a, b) {
                return null == a.which && (a.which = null != b.charCode ? b.charCode : b.keyCode), a
            }
        },
        mouseHooks: {
            props: "button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
            filter: function (a, b) {
                var c, e, f, g = b.button;
                return null == a.pageX && null != b.clientX && (c = a.target.ownerDocument || d, e = c.documentElement, f = c.body, a.pageX = b.clientX + (e && e.scrollLeft || f && f.scrollLeft || 0) - (e && e.clientLeft || f && f.clientLeft || 0), a.pageY = b.clientY + (e && e.scrollTop || f && f.scrollTop || 0) - (e && e.clientTop || f && f.clientTop || 0)), a.which || void 0 === g || (a.which = 1 & g ? 1 : 2 & g ? 3 : 4 & g ? 2 : 0), a
            }
        },
        fix: function (a) {
            if (a[n.expando]) return a;
            var b, c, e, f = a.type,
                g = a,
                h = this.fixHooks[f];
            h || (this.fixHooks[f] = h = ea.test(f) ? this.mouseHooks : da.test(f) ? this.keyHooks : {}), e = h.props ? this.props.concat(h.props) : this.props, a = new n.Event(g), b = e.length;
            while (b--) c = e[b], a[c] = g[c];
            return a.target || (a.target = d), 3 === a.target.nodeType && (a.target = a.target.parentNode), h.filter ? h.filter(a, g) : a
        },
        special: {
            load: {
                noBubble: !0
            },
            focus: {
                trigger: function () {
                    return this !== ia() && this.focus ? (this.focus(), !1) : void 0
                },
                delegateType: "focusin"
            },
            blur: {
                trigger: function () {
                    return this === ia() && this.blur ? (this.blur(), !1) : void 0
                },
                delegateType: "focusout"
            },
            click: {
                trigger: function () {
                    return "checkbox" === this.type && this.click && n.nodeName(this, "input") ? (this.click(), !1) : void 0
                },
                _default: function (a) {
                    return n.nodeName(a.target, "a")
                }
            },
            beforeunload: {
                postDispatch: function (a) {
                    void 0 !== a.result && a.originalEvent && (a.originalEvent.returnValue = a.result)
                }
            }
        }
    }, n.removeEvent = function (a, b, c) {
        a.removeEventListener && a.removeEventListener(b, c)
    }, n.Event = function (a, b) {
        return this instanceof n.Event ? (a && a.type ? (this.originalEvent = a, this.type = a.type, this.isDefaultPrevented = a.defaultPrevented || void 0 === a.defaultPrevented && a.returnValue === !1 ? ga : ha) : this.type = a, b && n.extend(this, b), this.timeStamp = a && a.timeStamp || n.now(), void(this[n.expando] = !0)) : new n.Event(a, b)
    }, n.Event.prototype = {
        constructor: n.Event,
        isDefaultPrevented: ha,
        isPropagationStopped: ha,
        isImmediatePropagationStopped: ha,
        isSimulated: !1,
        preventDefault: function () {
            var a = this.originalEvent;
            this.isDefaultPrevented = ga, a && !this.isSimulated && a.preventDefault()
        },
        stopPropagation: function () {
            var a = this.originalEvent;
            this.isPropagationStopped = ga, a && !this.isSimulated && a.stopPropagation()
        },
        stopImmediatePropagation: function () {
            var a = this.originalEvent;
            this.isImmediatePropagationStopped = ga, a && !this.isSimulated && a.stopImmediatePropagation(), this.stopPropagation()
        }
    }, n.each({
        mouseenter: "mouseover",
        mouseleave: "mouseout",
        pointerenter: "pointerover",
        pointerleave: "pointerout"
    }, function (a, b) {
        n.event.special[a] = {
            delegateType: b,
            bindType: b,
            handle: function (a) {
                var c, d = this,
                    e = a.relatedTarget,
                    f = a.handleObj;
                return e && (e === d || n.contains(d, e)) || (a.type = f.origType, c = f.handler.apply(this, arguments), a.type = b), c
            }
        }
    }), n.fn.extend({
        on: function (a, b, c, d) {
            return ja(this, a, b, c, d)
        },
        one: function (a, b, c, d) {
            return ja(this, a, b, c, d, 1)
        },
        off: function (a, b, c) {
            var d, e;
            if (a && a.preventDefault && a.handleObj) return d = a.handleObj, n(a.delegateTarget).off(d.namespace ? d.origType + "." + d.namespace : d.origType, d.selector, d.handler), this;
            if ("object" == typeof a) {
                for (e in a) this.off(e, b, a[e]);
                return this
            }
            return b !== !1 && "function" != typeof b || (c = b, b = void 0), c === !1 && (c = ha), this.each(function () {
                n.event.remove(this, a, c, b)
            })
        }
    });
    var ka = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,
        la = /<script|<style|<link/i,
        ma = /checked\s*(?:[^=]|=\s*.checked.)/i,
        na = /^true\/(.*)/,
        oa = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;

    function pa(a, b) {
        return n.nodeName(a, "table") && n.nodeName(11 !== b.nodeType ? b : b.firstChild, "tr") ? a.getElementsByTagName("tbody")[0] || a.appendChild(a.ownerDocument.createElement("tbody")) : a
    }

    function qa(a) {
        return a.type = (null !== a.getAttribute("type")) + "/" + a.type, a
    }

    function ra(a) {
        var b = na.exec(a.type);
        return b ? a.type = b[1] : a.removeAttribute("type"), a
    }

    function sa(a, b) {
        var c, d, e, f, g, h, i, j;
        if (1 === b.nodeType) {
            if (N.hasData(a) && (f = N.access(a), g = N.set(b, f), j = f.events)) {
                delete g.handle, g.events = {};
                for (e in j)
                    for (c = 0, d = j[e].length; d > c; c++) n.event.add(b, e, j[e][c])
            }
            O.hasData(a) && (h = O.access(a), i = n.extend({}, h), O.set(b, i))
        }
    }

    function ta(a, b) {
        var c = b.nodeName.toLowerCase();
        "input" === c && X.test(a.type) ? b.checked = a.checked : "input" !== c && "textarea" !== c || (b.defaultValue = a.defaultValue)
    }

    function ua(a, b, c, d) {
        b = f.apply([], b);
        var e, g, h, i, j, k, m = 0,
            o = a.length,
            p = o - 1,
            q = b[0],
            r = n.isFunction(q);
        if (r || o > 1 && "string" == typeof q && !l.checkClone && ma.test(q)) return a.each(function (e) {
            var f = a.eq(e);
            r && (b[0] = q.call(this, e, f.html())), ua(f, b, c, d)
        });
        if (o && (e = ca(b, a[0].ownerDocument, !1, a, d), g = e.firstChild, 1 === e.childNodes.length && (e = g), g || d)) {
            for (h = n.map(_(e, "script"), qa), i = h.length; o > m; m++) j = e, m !== p && (j = n.clone(j, !0, !0), i && n.merge(h, _(j, "script"))), c.call(a[m], j, m);
            if (i)
                for (k = h[h.length - 1].ownerDocument, n.map(h, ra), m = 0; i > m; m++) j = h[m], Z.test(j.type || "") && !N.access(j, "globalEval") && n.contains(k, j) && (j.src ? n._evalUrl && n._evalUrl(j.src) : n.globalEval(j.textContent.replace(oa, "")))
        }
        return a
    }

    function va(a, b, c) {
        for (var d, e = b ? n.filter(b, a) : a, f = 0; null != (d = e[f]); f++) c || 1 !== d.nodeType || n.cleanData(_(d)), d.parentNode && (c && n.contains(d.ownerDocument, d) && aa(_(d, "script")), d.parentNode.removeChild(d));
        return a
    }
    n.extend({
        htmlPrefilter: function (a) {
            return a.replace(ka, "<$1></$2>")
        },
        clone: function (a, b, c) {
            var d, e, f, g, h = a.cloneNode(!0),
                i = n.contains(a.ownerDocument, a);
            if (!(l.noCloneChecked || 1 !== a.nodeType && 11 !== a.nodeType || n.isXMLDoc(a)))
                for (g = _(h), f = _(a), d = 0, e = f.length; e > d; d++) ta(f[d], g[d]);
            if (b)
                if (c)
                    for (f = f || _(a), g = g || _(h), d = 0, e = f.length; e > d; d++) sa(f[d], g[d]);
                else sa(a, h);
            return g = _(h, "script"), g.length > 0 && aa(g, !i && _(a, "script")), h
        },
        cleanData: function (a) {
            for (var b, c, d, e = n.event.special, f = 0; void 0 !== (c = a[f]); f++)
                if (L(c)) {
                    if (b = c[N.expando]) {
                        if (b.events)
                            for (d in b.events) e[d] ? n.event.remove(c, d) : n.removeEvent(c, d, b.handle);
                        c[N.expando] = void 0
                    }
                    c[O.expando] && (c[O.expando] = void 0)
                }
        }
    }), n.fn.extend({
        domManip: ua,
        detach: function (a) {
            return va(this, a, !0)
        },
        remove: function (a) {
            return va(this, a)
        },
        text: function (a) {
            return K(this, function (a) {
                return void 0 === a ? n.text(this) : this.empty().each(function () {
                    1 !== this.nodeType && 11 !== this.nodeType && 9 !== this.nodeType || (this.textContent = a)
                })
            }, null, a, arguments.length)
        },
        append: function () {
            return ua(this, arguments, function (a) {
                if (1 === this.nodeType || 11 === this.nodeType || 9 === this.nodeType) {
                    var b = pa(this, a);
                    b.appendChild(a)
                }
            })
        },
        prepend: function () {
            return ua(this, arguments, function (a) {
                if (1 === this.nodeType || 11 === this.nodeType || 9 === this.nodeType) {
                    var b = pa(this, a);
                    b.insertBefore(a, b.firstChild)
                }
            })
        },
        before: function () {
            return ua(this, arguments, function (a) {
                this.parentNode && this.parentNode.insertBefore(a, this)
            })
        },
        after: function () {
            return ua(this, arguments, function (a) {
                this.parentNode && this.parentNode.insertBefore(a, this.nextSibling)
            })
        },
        empty: function () {
            for (var a, b = 0; null != (a = this[b]); b++) 1 === a.nodeType && (n.cleanData(_(a, !1)), a.textContent = "");
            return this
        },
        clone: function (a, b) {
            return a = null == a ? !1 : a, b = null == b ? a : b, this.map(function () {
                return n.clone(this, a, b)
            })
        },
        html: function (a) {
            return K(this, function (a) {
                var b = this[0] || {},
                    c = 0,
                    d = this.length;
                if (void 0 === a && 1 === b.nodeType) return b.innerHTML;
                if ("string" == typeof a && !la.test(a) && !$[(Y.exec(a) || ["", ""])[1].toLowerCase()]) {
                    a = n.htmlPrefilter(a);
                    try {
                        for (; d > c; c++) b = this[c] || {}, 1 === b.nodeType && (n.cleanData(_(b, !1)), b.innerHTML = a);
                        b = 0
                    } catch (e) {}
                }
                b && this.empty().append(a)
            }, null, a, arguments.length)
        },
        replaceWith: function () {
            var a = [];
            return ua(this, arguments, function (b) {
                var c = this.parentNode;
                n.inArray(this, a) < 0 && (n.cleanData(_(this)), c && c.replaceChild(b, this))
            }, a)
        }
    }), n.each({
        appendTo: "append",
        prependTo: "prepend",
        insertBefore: "before",
        insertAfter: "after",
        replaceAll: "replaceWith"
    }, function (a, b) {
        n.fn[a] = function (a) {
            for (var c, d = [], e = n(a), f = e.length - 1, h = 0; f >= h; h++) c = h === f ? this : this.clone(!0), n(e[h])[b](c), g.apply(d, c.get());
            return this.pushStack(d)
        }
    });
    var wa, xa = {
        HTML: "block",
        BODY: "block"
    };

    function ya(a, b) {
        var c = n(b.createElement(a)).appendTo(b.body),
            d = n.css(c[0], "display");
        return c.detach(), d
    }

    function za(a) {
        var b = d,
            c = xa[a];
        return c || (c = ya(a, b), "none" !== c && c || (wa = (wa || n("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement), b = wa[0].contentDocument, b.write(), b.close(), c = ya(a, b), wa.detach()), xa[a] = c), c
    }
    var Aa = /^margin/,
        Ba = new RegExp("^(" + S + ")(?!px)[a-z%]+$", "i"),
        Ca = function (b) {
            var c = b.ownerDocument.defaultView;
            return c && c.opener || (c = a), c.getComputedStyle(b)
        },
        Da = function (a, b, c, d) {
            var e, f, g = {};
            for (f in b) g[f] = a.style[f], a.style[f] = b[f];
            e = c.apply(a, d || []);
            for (f in b) a.style[f] = g[f];
            return e
        },
        Ea = d.documentElement;
    ! function () {
        var b, c, e, f, g = d.createElement("div"),
            h = d.createElement("div");
        if (h.style) {
            h.style.backgroundClip = "content-box", h.cloneNode(!0).style.backgroundClip = "", l.clearCloneStyle = "content-box" === h.style.backgroundClip, g.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute", g.appendChild(h);

            function i() {
                h.style.cssText = "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%", h.innerHTML = "", Ea.appendChild(g);
                var d = a.getComputedStyle(h);
                b = "1%" !== d.top, f = "2px" === d.marginLeft, c = "4px" === d.width, h.style.marginRight = "50%", e = "4px" === d.marginRight, Ea.removeChild(g)
            }
            n.extend(l, {
                pixelPosition: function () {
                    return i(), b
                },
                boxSizingReliable: function () {
                    return null == c && i(), c
                },
                pixelMarginRight: function () {
                    return null == c && i(), e
                },
                reliableMarginLeft: function () {
                    return null == c && i(), f
                },
                reliableMarginRight: function () {
                    var b, c = h.appendChild(d.createElement("div"));
                    return c.style.cssText = h.style.cssText = "-webkit-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0", c.style.marginRight = c.style.width = "0", h.style.width = "1px", Ea.appendChild(g), b = !parseFloat(a.getComputedStyle(c).marginRight), Ea.removeChild(g), h.removeChild(c), b
                }
            })
        }
    }();

    function Fa(a, b, c) {
        var d, e, f, g, h = a.style;
        return c = c || Ca(a), g = c ? c.getPropertyValue(b) || c[b] : void 0, "" !== g && void 0 !== g || n.contains(a.ownerDocument, a) || (g = n.style(a, b)), c && !l.pixelMarginRight() && Ba.test(g) && Aa.test(b) && (d = h.width, e = h.minWidth, f = h.maxWidth, h.minWidth = h.maxWidth = h.width = g, g = c.width, h.width = d, h.minWidth = e, h.maxWidth = f), void 0 !== g ? g + "" : g
    }

    function Ga(a, b) {
        return {
            get: function () {
                return a() ? void delete this.get : (this.get = b).apply(this, arguments)
            }
        }
    }
    var Ha = /^(none|table(?!-c[ea]).+)/,
        Ia = {
            position: "absolute",
            visibility: "hidden",
            display: "block"
        },
        Ja = {
            letterSpacing: "0",
            fontWeight: "400"
        },
        Ka = ["Webkit", "O", "Moz", "ms"],
        La = d.createElement("div").style;

    function Ma(a) {
        if (a in La) return a;
        var b = a[0].toUpperCase() + a.slice(1),
            c = Ka.length;
        while (c--)
            if (a = Ka[c] + b, a in La) return a
    }

    function Na(a, b, c) {
        var d = T.exec(b);
        return d ? Math.max(0, d[2] - (c || 0)) + (d[3] || "px") : b
    }

    function Oa(a, b, c, d, e) {
        for (var f = c === (d ? "border" : "content") ? 4 : "width" === b ? 1 : 0, g = 0; 4 > f; f += 2) "margin" === c && (g += n.css(a, c + U[f], !0, e)), d ? ("content" === c && (g -= n.css(a, "padding" + U[f], !0, e)), "margin" !== c && (g -= n.css(a, "border" + U[f] + "Width", !0, e))) : (g += n.css(a, "padding" + U[f], !0, e), "padding" !== c && (g += n.css(a, "border" + U[f] + "Width", !0, e)));
        return g
    }

    function Pa(a, b, c) {
        var d = !0,
            e = "width" === b ? a.offsetWidth : a.offsetHeight,
            f = Ca(a),
            g = "border-box" === n.css(a, "boxSizing", !1, f);
        if (0 >= e || null == e) {
            if (e = Fa(a, b, f), (0 > e || null == e) && (e = a.style[b]), Ba.test(e)) return e;
            d = g && (l.boxSizingReliable() || e === a.style[b]), e = parseFloat(e) || 0
        }
        return e + Oa(a, b, c || (g ? "border" : "content"), d, f) + "px"
    }

    function Qa(a, b) {
        for (var c, d, e, f = [], g = 0, h = a.length; h > g; g++) d = a[g], d.style && (f[g] = N.get(d, "olddisplay"), c = d.style.display, b ? (f[g] || "none" !== c || (d.style.display = ""), "" === d.style.display && V(d) && (f[g] = N.access(d, "olddisplay", za(d.nodeName)))) : (e = V(d), "none" === c && e || N.set(d, "olddisplay", e ? c : n.css(d, "display"))));
        for (g = 0; h > g; g++) d = a[g], d.style && (b && "none" !== d.style.display && "" !== d.style.display || (d.style.display = b ? f[g] || "" : "none"));
        return a
    }
    n.extend({
        cssHooks: {
            opacity: {
                get: function (a, b) {
                    if (b) {
                        var c = Fa(a, "opacity");
                        return "" === c ? "1" : c
                    }
                }
            }
        },
        cssNumber: {
            animationIterationCount: !0,
            columnCount: !0,
            fillOpacity: !0,
            flexGrow: !0,
            flexShrink: !0,
            fontWeight: !0,
            lineHeight: !0,
            opacity: !0,
            order: !0,
            orphans: !0,
            widows: !0,
            zIndex: !0,
            zoom: !0
        },
        cssProps: {
            "float": "cssFloat"
        },
        style: function (a, b, c, d) {
            if (a && 3 !== a.nodeType && 8 !== a.nodeType && a.style) {
                var e, f, g, h = n.camelCase(b),
                    i = a.style;
                return b = n.cssProps[h] || (n.cssProps[h] = Ma(h) || h), g = n.cssHooks[b] || n.cssHooks[h], void 0 === c ? g && "get" in g && void 0 !== (e = g.get(a, !1, d)) ? e : i[b] : (f = typeof c, "string" === f && (e = T.exec(c)) && e[1] && (c = W(a, b, e), f = "number"), null != c && c === c && ("number" === f && (c += e && e[3] || (n.cssNumber[h] ? "" : "px")), l.clearCloneStyle || "" !== c || 0 !== b.indexOf("background") || (i[b] = "inherit"), g && "set" in g && void 0 === (c = g.set(a, c, d)) || (i[b] = c)), void 0)
            }
        },
        css: function (a, b, c, d) {
            var e, f, g, h = n.camelCase(b);
            return b = n.cssProps[h] || (n.cssProps[h] = Ma(h) || h), g = n.cssHooks[b] || n.cssHooks[h], g && "get" in g && (e = g.get(a, !0, c)), void 0 === e && (e = Fa(a, b, d)), "normal" === e && b in Ja && (e = Ja[b]), "" === c || c ? (f = parseFloat(e), c === !0 || isFinite(f) ? f || 0 : e) : e
        }
    }), n.each(["height", "width"], function (a, b) {
        n.cssHooks[b] = {
            get: function (a, c, d) {
                return c ? Ha.test(n.css(a, "display")) && 0 === a.offsetWidth ? Da(a, Ia, function () {
                    return Pa(a, b, d)
                }) : Pa(a, b, d) : void 0
            },
            set: function (a, c, d) {
                var e, f = d && Ca(a),
                    g = d && Oa(a, b, d, "border-box" === n.css(a, "boxSizing", !1, f), f);
                return g && (e = T.exec(c)) && "px" !== (e[3] || "px") && (a.style[b] = c, c = n.css(a, b)), Na(a, c, g)
            }
        }
    }), n.cssHooks.marginLeft = Ga(l.reliableMarginLeft, function (a, b) {
        return b ? (parseFloat(Fa(a, "marginLeft")) || a.getBoundingClientRect().left - Da(a, {
            marginLeft: 0
        }, function () {
            return a.getBoundingClientRect().left
        })) + "px" : void 0
    }), n.cssHooks.marginRight = Ga(l.reliableMarginRight, function (a, b) {
        return b ? Da(a, {
            display: "inline-block"
        }, Fa, [a, "marginRight"]) : void 0
    }), n.each({
        margin: "",
        padding: "",
        border: "Width"
    }, function (a, b) {
        n.cssHooks[a + b] = {
            expand: function (c) {
                for (var d = 0, e = {}, f = "string" == typeof c ? c.split(" ") : [c]; 4 > d; d++) e[a + U[d] + b] = f[d] || f[d - 2] || f[0];
                return e
            }
        }, Aa.test(a) || (n.cssHooks[a + b].set = Na)
    }), n.fn.extend({
        css: function (a, b) {
            return K(this, function (a, b, c) {
                var d, e, f = {},
                    g = 0;
                if (n.isArray(b)) {
                    for (d = Ca(a), e = b.length; e > g; g++) f[b[g]] = n.css(a, b[g], !1, d);
                    return f
                }
                return void 0 !== c ? n.style(a, b, c) : n.css(a, b)
            }, a, b, arguments.length > 1)
        },
        show: function () {
            return Qa(this, !0)
        },
        hide: function () {
            return Qa(this)
        },
        toggle: function (a) {
            return "boolean" == typeof a ? a ? this.show() : this.hide() : this.each(function () {
                V(this) ? n(this).show() : n(this).hide()
            })
        }
    });

    function Ra(a, b, c, d, e) {
        return new Ra.prototype.init(a, b, c, d, e)
    }
    n.Tween = Ra, Ra.prototype = {
        constructor: Ra,
        init: function (a, b, c, d, e, f) {
            this.elem = a, this.prop = c, this.easing = e || n.easing._default, this.options = b, this.start = this.now = this.cur(), this.end = d, this.unit = f || (n.cssNumber[c] ? "" : "px")
        },
        cur: function () {
            var a = Ra.propHooks[this.prop];
            return a && a.get ? a.get(this) : Ra.propHooks._default.get(this)
        },
        run: function (a) {
            var b, c = Ra.propHooks[this.prop];
            return this.options.duration ? this.pos = b = n.easing[this.easing](a, this.options.duration * a, 0, 1, this.options.duration) : this.pos = b = a, this.now = (this.end - this.start) * b + this.start, this.options.step && this.options.step.call(this.elem, this.now, this), c && c.set ? c.set(this) : Ra.propHooks._default.set(this), this
        }
    }, Ra.prototype.init.prototype = Ra.prototype, Ra.propHooks = {
        _default: {
            get: function (a) {
                var b;
                return 1 !== a.elem.nodeType || null != a.elem[a.prop] && null == a.elem.style[a.prop] ? a.elem[a.prop] : (b = n.css(a.elem, a.prop, ""), b && "auto" !== b ? b : 0)
            },
            set: function (a) {
                n.fx.step[a.prop] ? n.fx.step[a.prop](a) : 1 !== a.elem.nodeType || null == a.elem.style[n.cssProps[a.prop]] && !n.cssHooks[a.prop] ? a.elem[a.prop] = a.now : n.style(a.elem, a.prop, a.now + a.unit)
            }
        }
    }, Ra.propHooks.scrollTop = Ra.propHooks.scrollLeft = {
        set: function (a) {
            a.elem.nodeType && a.elem.parentNode && (a.elem[a.prop] = a.now)
        }
    }, n.easing = {
        linear: function (a) {
            return a
        },
        swing: function (a) {
            return .5 - Math.cos(a * Math.PI) / 2
        },
        _default: "swing"
    }, n.fx = Ra.prototype.init, n.fx.step = {};
    var Sa, Ta, Ua = /^(?:toggle|show|hide)$/,
        Va = /queueHooks$/;

    function Wa() {
        return a.setTimeout(function () {
            Sa = void 0
        }), Sa = n.now()
    }

    function Xa(a, b) {
        var c, d = 0,
            e = {
                height: a
            };
        for (b = b ? 1 : 0; 4 > d; d += 2 - b) c = U[d], e["margin" + c] = e["padding" + c] = a;
        return b && (e.opacity = e.width = a), e
    }

    function Ya(a, b, c) {
        for (var d, e = (_a.tweeners[b] || []).concat(_a.tweeners["*"]), f = 0, g = e.length; g > f; f++)
            if (d = e[f].call(c, b, a)) return d
    }

    function Za(a, b, c) {
        var d, e, f, g, h, i, j, k, l = this,
            m = {},
            o = a.style,
            p = a.nodeType && V(a),
            q = N.get(a, "fxshow");
        c.queue || (h = n._queueHooks(a, "fx"), null == h.unqueued && (h.unqueued = 0, i = h.empty.fire, h.empty.fire = function () {
            h.unqueued || i()
        }), h.unqueued++, l.always(function () {
            l.always(function () {
                h.unqueued--, n.queue(a, "fx").length || h.empty.fire()
            })
        })), 1 === a.nodeType && ("height" in b || "width" in b) && (c.overflow = [o.overflow, o.overflowX, o.overflowY], j = n.css(a, "display"), k = "none" === j ? N.get(a, "olddisplay") || za(a.nodeName) : j, "inline" === k && "none" === n.css(a, "float") && (o.display = "inline-block")), c.overflow && (o.overflow = "hidden", l.always(function () {
            o.overflow = c.overflow[0], o.overflowX = c.overflow[1], o.overflowY = c.overflow[2]
        }));
        for (d in b)
            if (e = b[d], Ua.exec(e)) {
                if (delete b[d], f = f || "toggle" === e, e === (p ? "hide" : "show")) {
                    if ("show" !== e || !q || void 0 === q[d]) continue;
                    p = !0
                }
                m[d] = q && q[d] || n.style(a, d)
            } else j = void 0;
        if (n.isEmptyObject(m)) "inline" === ("none" === j ? za(a.nodeName) : j) && (o.display = j);
        else {
            q ? "hidden" in q && (p = q.hidden) : q = N.access(a, "fxshow", {}), f && (q.hidden = !p), p ? n(a).show() : l.done(function () {
                n(a).hide()
            }), l.done(function () {
                var b;
                N.remove(a, "fxshow");
                for (b in m) n.style(a, b, m[b])
            });
            for (d in m) g = Ya(p ? q[d] : 0, d, l), d in q || (q[d] = g.start, p && (g.end = g.start, g.start = "width" === d || "height" === d ? 1 : 0))
        }
    }

    function $a(a, b) {
        var c, d, e, f, g;
        for (c in a)
            if (d = n.camelCase(c), e = b[d], f = a[c], n.isArray(f) && (e = f[1], f = a[c] = f[0]), c !== d && (a[d] = f, delete a[c]), g = n.cssHooks[d], g && "expand" in g) {
                f = g.expand(f), delete a[d];
                for (c in f) c in a || (a[c] = f[c], b[c] = e)
            } else b[d] = e
    }

    function _a(a, b, c) {
        var d, e, f = 0,
            g = _a.prefilters.length,
            h = n.Deferred().always(function () {
                delete i.elem
            }),
            i = function () {
                if (e) return !1;
                for (var b = Sa || Wa(), c = Math.max(0, j.startTime + j.duration - b), d = c / j.duration || 0, f = 1 - d, g = 0, i = j.tweens.length; i > g; g++) j.tweens[g].run(f);
                return h.notifyWith(a, [j, f, c]), 1 > f && i ? c : (h.resolveWith(a, [j]), !1)
            },
            j = h.promise({
                elem: a,
                props: n.extend({}, b),
                opts: n.extend(!0, {
                    specialEasing: {},
                    easing: n.easing._default
                }, c),
                originalProperties: b,
                originalOptions: c,
                startTime: Sa || Wa(),
                duration: c.duration,
                tweens: [],
                createTween: function (b, c) {
                    var d = n.Tween(a, j.opts, b, c, j.opts.specialEasing[b] || j.opts.easing);
                    return j.tweens.push(d), d
                },
                stop: function (b) {
                    var c = 0,
                        d = b ? j.tweens.length : 0;
                    if (e) return this;
                    for (e = !0; d > c; c++) j.tweens[c].run(1);
                    return b ? (h.notifyWith(a, [j, 1, 0]), h.resolveWith(a, [j, b])) : h.rejectWith(a, [j, b]), this
                }
            }),
            k = j.props;
        for ($a(k, j.opts.specialEasing); g > f; f++)
            if (d = _a.prefilters[f].call(j, a, k, j.opts)) return n.isFunction(d.stop) && (n._queueHooks(j.elem, j.opts.queue).stop = n.proxy(d.stop, d)), d;
        return n.map(k, Ya, j), n.isFunction(j.opts.start) && j.opts.start.call(a, j), n.fx.timer(n.extend(i, {
            elem: a,
            anim: j,
            queue: j.opts.queue
        })), j.progress(j.opts.progress).done(j.opts.done, j.opts.complete).fail(j.opts.fail).always(j.opts.always)
    }
    n.Animation = n.extend(_a, {
            tweeners: {
                "*": [function (a, b) {
                    var c = this.createTween(a, b);
                    return W(c.elem, a, T.exec(b), c), c
                }]
            },
            tweener: function (a, b) {
                n.isFunction(a) ? (b = a, a = ["*"]) : a = a.match(G);
                for (var c, d = 0, e = a.length; e > d; d++) c = a[d], _a.tweeners[c] = _a.tweeners[c] || [], _a.tweeners[c].unshift(b)
            },
            prefilters: [Za],
            prefilter: function (a, b) {
                b ? _a.prefilters.unshift(a) : _a.prefilters.push(a)
            }
        }), n.speed = function (a, b, c) {
            var d = a && "object" == typeof a ? n.extend({}, a) : {
                complete: c || !c && b || n.isFunction(a) && a,
                duration: a,
                easing: c && b || b && !n.isFunction(b) && b
            };
            return d.duration = n.fx.off ? 0 : "number" == typeof d.duration ? d.duration : d.duration in n.fx.speeds ? n.fx.speeds[d.duration] : n.fx.speeds._default, null != d.queue && d.queue !== !0 || (d.queue = "fx"), d.old = d.complete, d.complete = function () {
                n.isFunction(d.old) && d.old.call(this), d.queue && n.dequeue(this, d.queue)
            }, d
        }, n.fn.extend({
            fadeTo: function (a, b, c, d) {
                return this.filter(V).css("opacity", 0).show().end().animate({
                    opacity: b
                }, a, c, d)
            },
            animate: function (a, b, c, d) {
                var e = n.isEmptyObject(a),
                    f = n.speed(b, c, d),
                    g = function () {
                        var b = _a(this, n.extend({}, a), f);
                        (e || N.get(this, "finish")) && b.stop(!0)
                    };
                return g.finish = g, e || f.queue === !1 ? this.each(g) : this.queue(f.queue, g)
            },
            stop: function (a, b, c) {
                var d = function (a) {
                    var b = a.stop;
                    delete a.stop, b(c)
                };
                return "string" != typeof a && (c = b, b = a, a = void 0), b && a !== !1 && this.queue(a || "fx", []), this.each(function () {
                    var b = !0,
                        e = null != a && a + "queueHooks",
                        f = n.timers,
                        g = N.get(this);
                    if (e) g[e] && g[e].stop && d(g[e]);
                    else
                        for (e in g) g[e] && g[e].stop && Va.test(e) && d(g[e]);
                    for (e = f.length; e--;) f[e].elem !== this || null != a && f[e].queue !== a || (f[e].anim.stop(c), b = !1, f.splice(e, 1));
                    !b && c || n.dequeue(this, a)
                })
            },
            finish: function (a) {
                return a !== !1 && (a = a || "fx"), this.each(function () {
                    var b, c = N.get(this),
                        d = c[a + "queue"],
                        e = c[a + "queueHooks"],
                        f = n.timers,
                        g = d ? d.length : 0;
                    for (c.finish = !0, n.queue(this, a, []), e && e.stop && e.stop.call(this, !0), b = f.length; b--;) f[b].elem === this && f[b].queue === a && (f[b].anim.stop(!0), f.splice(b, 1));
                    for (b = 0; g > b; b++) d[b] && d[b].finish && d[b].finish.call(this);
                    delete c.finish
                })
            }
        }), n.each(["toggle", "show", "hide"], function (a, b) {
            var c = n.fn[b];
            n.fn[b] = function (a, d, e) {
                return null == a || "boolean" == typeof a ? c.apply(this, arguments) : this.animate(Xa(b, !0), a, d, e)
            }
        }), n.each({
            slideDown: Xa("show"),
            slideUp: Xa("hide"),
            slideToggle: Xa("toggle"),
            fadeIn: {
                opacity: "show"
            },
            fadeOut: {
                opacity: "hide"
            },
            fadeToggle: {
                opacity: "toggle"
            }
        }, function (a, b) {
            n.fn[a] = function (a, c, d) {
                return this.animate(b, a, c, d)
            }
        }), n.timers = [], n.fx.tick = function () {
            var a, b = 0,
                c = n.timers;
            for (Sa = n.now(); b < c.length; b++) a = c[b], a() || c[b] !== a || c.splice(b--, 1);
            c.length || n.fx.stop(), Sa = void 0
        }, n.fx.timer = function (a) {
            n.timers.push(a), a() ? n.fx.start() : n.timers.pop()
        }, n.fx.interval = 13, n.fx.start = function () {
            Ta || (Ta = a.setInterval(n.fx.tick, n.fx.interval))
        }, n.fx.stop = function () {
            a.clearInterval(Ta), Ta = null
        }, n.fx.speeds = {
            slow: 600,
            fast: 200,
            _default: 400
        }, n.fn.delay = function (b, c) {
            return b = n.fx ? n.fx.speeds[b] || b : b, c = c || "fx", this.queue(c, function (c, d) {
                var e = a.setTimeout(c, b);
                d.stop = function () {
                    a.clearTimeout(e)
                }
            })
        },
        function () {
            var a = d.createElement("input"),
                b = d.createElement("select"),
                c = b.appendChild(d.createElement("option"));
            a.type = "checkbox", l.checkOn = "" !== a.value, l.optSelected = c.selected, b.disabled = !0, l.optDisabled = !c.disabled, a = d.createElement("input"), a.value = "t", a.type = "radio", l.radioValue = "t" === a.value
        }();
    var ab, bb = n.expr.attrHandle;
    n.fn.extend({
        attr: function (a, b) {
            return K(this, n.attr, a, b, arguments.length > 1)
        },
        removeAttr: function (a) {
            return this.each(function () {
                n.removeAttr(this, a)
            })
        }
    }), n.extend({
        attr: function (a, b, c) {
            var d, e, f = a.nodeType;
            if (3 !== f && 8 !== f && 2 !== f) return "undefined" == typeof a.getAttribute ? n.prop(a, b, c) : (1 === f && n.isXMLDoc(a) || (b = b.toLowerCase(), e = n.attrHooks[b] || (n.expr.match.bool.test(b) ? ab : void 0)), void 0 !== c ? null === c ? void n.removeAttr(a, b) : e && "set" in e && void 0 !== (d = e.set(a, c, b)) ? d : (a.setAttribute(b, c + ""), c) : e && "get" in e && null !== (d = e.get(a, b)) ? d : (d = n.find.attr(a, b), null == d ? void 0 : d))
        },
        attrHooks: {
            type: {
                set: function (a, b) {
                    if (!l.radioValue && "radio" === b && n.nodeName(a, "input")) {
                        var c = a.value;
                        return a.setAttribute("type", b), c && (a.value = c), b
                    }
                }
            }
        },
        removeAttr: function (a, b) {
            var c, d, e = 0,
                f = b && b.match(G);
            if (f && 1 === a.nodeType)
                while (c = f[e++]) d = n.propFix[c] || c, n.expr.match.bool.test(c) && (a[d] = !1), a.removeAttribute(c)
        }
    }), ab = {
        set: function (a, b, c) {
            return b === !1 ? n.removeAttr(a, c) : a.setAttribute(c, c), c
        }
    }, n.each(n.expr.match.bool.source.match(/\w+/g), function (a, b) {
        var c = bb[b] || n.find.attr;
        bb[b] = function (a, b, d) {
            var e, f;
            return d || (f = bb[b], bb[b] = e, e = null != c(a, b, d) ? b.toLowerCase() : null, bb[b] = f), e
        }
    });
    var cb = /^(?:input|select|textarea|button)$/i,
        db = /^(?:a|area)$/i;
    n.fn.extend({
        prop: function (a, b) {
            return K(this, n.prop, a, b, arguments.length > 1)
        },
        removeProp: function (a) {
            return this.each(function () {
                delete this[n.propFix[a] || a]
            })
        }
    }), n.extend({
        prop: function (a, b, c) {
            var d, e, f = a.nodeType;
            if (3 !== f && 8 !== f && 2 !== f) return 1 === f && n.isXMLDoc(a) || (b = n.propFix[b] || b, e = n.propHooks[b]),
                void 0 !== c ? e && "set" in e && void 0 !== (d = e.set(a, c, b)) ? d : a[b] = c : e && "get" in e && null !== (d = e.get(a, b)) ? d : a[b]
        },
        propHooks: {
            tabIndex: {
                get: function (a) {
                    var b = n.find.attr(a, "tabindex");
                    return b ? parseInt(b, 10) : cb.test(a.nodeName) || db.test(a.nodeName) && a.href ? 0 : -1
                }
            }
        },
        propFix: {
            "for": "htmlFor",
            "class": "className"
        }
    }), l.optSelected || (n.propHooks.selected = {
        get: function (a) {
            var b = a.parentNode;
            return b && b.parentNode && b.parentNode.selectedIndex, null
        },
        set: function (a) {
            var b = a.parentNode;
            b && (b.selectedIndex, b.parentNode && b.parentNode.selectedIndex)
        }
    }), n.each(["tabIndex", "readOnly", "maxLength", "cellSpacing", "cellPadding", "rowSpan", "colSpan", "useMap", "frameBorder", "contentEditable"], function () {
        n.propFix[this.toLowerCase()] = this
    });
    var eb = /[\t\r\n\f]/g;

    function fb(a) {
        return a.getAttribute && a.getAttribute("class") || ""
    }
    n.fn.extend({
        addClass: function (a) {
            var b, c, d, e, f, g, h, i = 0;
            if (n.isFunction(a)) return this.each(function (b) {
                n(this).addClass(a.call(this, b, fb(this)))
            });
            if ("string" == typeof a && a) {
                b = a.match(G) || [];
                while (c = this[i++])
                    if (e = fb(c), d = 1 === c.nodeType && (" " + e + " ").replace(eb, " ")) {
                        g = 0;
                        while (f = b[g++]) d.indexOf(" " + f + " ") < 0 && (d += f + " ");
                        h = n.trim(d), e !== h && c.setAttribute("class", h)
                    }
            }
            return this
        },
        removeClass: function (a) {
            var b, c, d, e, f, g, h, i = 0;
            if (n.isFunction(a)) return this.each(function (b) {
                n(this).removeClass(a.call(this, b, fb(this)))
            });
            if (!arguments.length) return this.attr("class", "");
            if ("string" == typeof a && a) {
                b = a.match(G) || [];
                while (c = this[i++])
                    if (e = fb(c), d = 1 === c.nodeType && (" " + e + " ").replace(eb, " ")) {
                        g = 0;
                        while (f = b[g++])
                            while (d.indexOf(" " + f + " ") > -1) d = d.replace(" " + f + " ", " ");
                        h = n.trim(d), e !== h && c.setAttribute("class", h)
                    }
            }
            return this
        },
        toggleClass: function (a, b) {
            var c = typeof a;
            return "boolean" == typeof b && "string" === c ? b ? this.addClass(a) : this.removeClass(a) : n.isFunction(a) ? this.each(function (c) {
                n(this).toggleClass(a.call(this, c, fb(this), b), b)
            }) : this.each(function () {
                var b, d, e, f;
                if ("string" === c) {
                    d = 0, e = n(this), f = a.match(G) || [];
                    while (b = f[d++]) e.hasClass(b) ? e.removeClass(b) : e.addClass(b)
                } else void 0 !== a && "boolean" !== c || (b = fb(this), b && N.set(this, "__className__", b), this.setAttribute && this.setAttribute("class", b || a === !1 ? "" : N.get(this, "__className__") || ""))
            })
        },
        hasClass: function (a) {
            var b, c, d = 0;
            b = " " + a + " ";
            while (c = this[d++])
                if (1 === c.nodeType && (" " + fb(c) + " ").replace(eb, " ").indexOf(b) > -1) return !0;
            return !1
        }
    });
    var gb = /\r/g,
        hb = /[\x20\t\r\n\f]+/g;
    n.fn.extend({
        val: function (a) {
            var b, c, d, e = this[0]; {
                if (arguments.length) return d = n.isFunction(a), this.each(function (c) {
                    var e;
                    1 === this.nodeType && (e = d ? a.call(this, c, n(this).val()) : a, null == e ? e = "" : "number" == typeof e ? e += "" : n.isArray(e) && (e = n.map(e, function (a) {
                        return null == a ? "" : a + ""
                    })), b = n.valHooks[this.type] || n.valHooks[this.nodeName.toLowerCase()], b && "set" in b && void 0 !== b.set(this, e, "value") || (this.value = e))
                });
                if (e) return b = n.valHooks[e.type] || n.valHooks[e.nodeName.toLowerCase()], b && "get" in b && void 0 !== (c = b.get(e, "value")) ? c : (c = e.value, "string" == typeof c ? c.replace(gb, "") : null == c ? "" : c)
            }
        }
    }), n.extend({
        valHooks: {
            option: {
                get: function (a) {
                    var b = n.find.attr(a, "value");
                    return null != b ? b : n.trim(n.text(a)).replace(hb, " ")
                }
            },
            select: {
                get: function (a) {
                    for (var b, c, d = a.options, e = a.selectedIndex, f = "select-one" === a.type || 0 > e, g = f ? null : [], h = f ? e + 1 : d.length, i = 0 > e ? h : f ? e : 0; h > i; i++)
                        if (c = d[i], (c.selected || i === e) && (l.optDisabled ? !c.disabled : null === c.getAttribute("disabled")) && (!c.parentNode.disabled || !n.nodeName(c.parentNode, "optgroup"))) {
                            if (b = n(c).val(), f) return b;
                            g.push(b)
                        } return g
                },
                set: function (a, b) {
                    var c, d, e = a.options,
                        f = n.makeArray(b),
                        g = e.length;
                    while (g--) d = e[g], (d.selected = n.inArray(n.valHooks.option.get(d), f) > -1) && (c = !0);
                    return c || (a.selectedIndex = -1), f
                }
            }
        }
    }), n.each(["radio", "checkbox"], function () {
        n.valHooks[this] = {
            set: function (a, b) {
                return n.isArray(b) ? a.checked = n.inArray(n(a).val(), b) > -1 : void 0
            }
        }, l.checkOn || (n.valHooks[this].get = function (a) {
            return null === a.getAttribute("value") ? "on" : a.value
        })
    });
    var ib = /^(?:focusinfocus|focusoutblur)$/;
    n.extend(n.event, {
        trigger: function (b, c, e, f) {
            var g, h, i, j, l, m, o, p = [e || d],
                q = k.call(b, "type") ? b.type : b,
                r = k.call(b, "namespace") ? b.namespace.split(".") : [];
            if (h = i = e = e || d, 3 !== e.nodeType && 8 !== e.nodeType && !ib.test(q + n.event.triggered) && (q.indexOf(".") > -1 && (r = q.split("."), q = r.shift(), r.sort()), l = q.indexOf(":") < 0 && "on" + q, b = b[n.expando] ? b : new n.Event(q, "object" == typeof b && b), b.isTrigger = f ? 2 : 3, b.namespace = r.join("."), b.rnamespace = b.namespace ? new RegExp("(^|\\.)" + r.join("\\.(?:.*\\.|)") + "(\\.|$)") : null, b.result = void 0, b.target || (b.target = e), c = null == c ? [b] : n.makeArray(c, [b]), o = n.event.special[q] || {}, f || !o.trigger || o.trigger.apply(e, c) !== !1)) {
                if (!f && !o.noBubble && !n.isWindow(e)) {
                    for (j = o.delegateType || q, ib.test(j + q) || (h = h.parentNode); h; h = h.parentNode) p.push(h), i = h;
                    i === (e.ownerDocument || d) && p.push(i.defaultView || i.parentWindow || a)
                }
                g = 0;
                while ((h = p[g++]) && !b.isPropagationStopped()) b.type = g > 1 ? j : o.bindType || q, m = (N.get(h, "events") || {})[b.type] && N.get(h, "handle"), m && m.apply(h, c), m = l && h[l], m && m.apply && L(h) && (b.result = m.apply(h, c), b.result === !1 && b.preventDefault());
                return b.type = q, f || b.isDefaultPrevented() || o._default && o._default.apply(p.pop(), c) !== !1 || !L(e) || l && n.isFunction(e[q]) && !n.isWindow(e) && (i = e[l], i && (e[l] = null), n.event.triggered = q, e[q](), n.event.triggered = void 0, i && (e[l] = i)), b.result
            }
        },
        simulate: function (a, b, c) {
            var d = n.extend(new n.Event, c, {
                type: a,
                isSimulated: !0
            });
            n.event.trigger(d, null, b)
        }
    }), n.fn.extend({
        trigger: function (a, b) {
            return this.each(function () {
                n.event.trigger(a, b, this)
            })
        },
        triggerHandler: function (a, b) {
            var c = this[0];
            return c ? n.event.trigger(a, b, c, !0) : void 0
        }
    }), n.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "), function (a, b) {
        n.fn[b] = function (a, c) {
            return arguments.length > 0 ? this.on(b, null, a, c) : this.trigger(b)
        }
    }), n.fn.extend({
        hover: function (a, b) {
            return this.mouseenter(a).mouseleave(b || a)
        }
    }), l.focusin = "onfocusin" in a, l.focusin || n.each({
        focus: "focusin",
        blur: "focusout"
    }, function (a, b) {
        var c = function (a) {
            n.event.simulate(b, a.target, n.event.fix(a))
        };
        n.event.special[b] = {
            setup: function () {
                var d = this.ownerDocument || this,
                    e = N.access(d, b);
                e || d.addEventListener(a, c, !0), N.access(d, b, (e || 0) + 1)
            },
            teardown: function () {
                var d = this.ownerDocument || this,
                    e = N.access(d, b) - 1;
                e ? N.access(d, b, e) : (d.removeEventListener(a, c, !0), N.remove(d, b))
            }
        }
    });
    var jb = a.location,
        kb = n.now(),
        lb = /\?/;
    n.parseJSON = function (a) {
        return JSON.parse(a + "")
    }, n.parseXML = function (b) {
        var c;
        if (!b || "string" != typeof b) return null;
        try {
            c = (new a.DOMParser).parseFromString(b, "text/xml")
        } catch (d) {
            c = void 0
        }
        return c && !c.getElementsByTagName("parsererror").length || n.error("Invalid XML: " + b), c
    };
    var mb = /#.*$/,
        nb = /([?&])_=[^&]*/,
        ob = /^(.*?):[ \t]*([^\r\n]*)$/gm,
        pb = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
        qb = /^(?:GET|HEAD)$/,
        rb = /^\/\//,
        sb = {},
        tb = {},
        ub = "*/".concat("*"),
        vb = d.createElement("a");
    vb.href = jb.href;

    function wb(a) {
        return function (b, c) {
            "string" != typeof b && (c = b, b = "*");
            var d, e = 0,
                f = b.toLowerCase().match(G) || [];
            if (n.isFunction(c))
                while (d = f[e++]) "+" === d[0] ? (d = d.slice(1) || "*", (a[d] = a[d] || []).unshift(c)) : (a[d] = a[d] || []).push(c)
        }
    }

    function xb(a, b, c, d) {
        var e = {},
            f = a === tb;

        function g(h) {
            var i;
            return e[h] = !0, n.each(a[h] || [], function (a, h) {
                var j = h(b, c, d);
                return "string" != typeof j || f || e[j] ? f ? !(i = j) : void 0 : (b.dataTypes.unshift(j), g(j), !1)
            }), i
        }
        return g(b.dataTypes[0]) || !e["*"] && g("*")
    }

    function yb(a, b) {
        var c, d, e = n.ajaxSettings.flatOptions || {};
        for (c in b) void 0 !== b[c] && ((e[c] ? a : d || (d = {}))[c] = b[c]);
        return d && n.extend(!0, a, d), a
    }

    function zb(a, b, c) {
        var d, e, f, g, h = a.contents,
            i = a.dataTypes;
        while ("*" === i[0]) i.shift(), void 0 === d && (d = a.mimeType || b.getResponseHeader("Content-Type"));
        if (d)
            for (e in h)
                if (h[e] && h[e].test(d)) {
                    i.unshift(e);
                    break
                } if (i[0] in c) f = i[0];
        else {
            for (e in c) {
                if (!i[0] || a.converters[e + " " + i[0]]) {
                    f = e;
                    break
                }
                g || (g = e)
            }
            f = f || g
        }
        return f ? (f !== i[0] && i.unshift(f), c[f]) : void 0
    }

    function Ab(a, b, c, d) {
        var e, f, g, h, i, j = {},
            k = a.dataTypes.slice();
        if (k[1])
            for (g in a.converters) j[g.toLowerCase()] = a.converters[g];
        f = k.shift();
        while (f)
            if (a.responseFields[f] && (c[a.responseFields[f]] = b), !i && d && a.dataFilter && (b = a.dataFilter(b, a.dataType)), i = f, f = k.shift())
                if ("*" === f) f = i;
                else if ("*" !== i && i !== f) {
            if (g = j[i + " " + f] || j["* " + f], !g)
                for (e in j)
                    if (h = e.split(" "), h[1] === f && (g = j[i + " " + h[0]] || j["* " + h[0]])) {
                        g === !0 ? g = j[e] : j[e] !== !0 && (f = h[0], k.unshift(h[1]));
                        break
                    } if (g !== !0)
                if (g && a["throws"]) b = g(b);
                else try {
                    b = g(b)
                } catch (l) {
                    return {
                        state: "parsererror",
                        error: g ? l : "No conversion from " + i + " to " + f
                    }
                }
        }
        return {
            state: "success",
            data: b
        }
    }
    n.extend({
        active: 0,
        lastModified: {},
        etag: {},
        ajaxSettings: {
            url: jb.href,
            type: "GET",
            isLocal: pb.test(jb.protocol),
            global: !0,
            processData: !0,
            async: !0,
            contentType: "application/x-www-form-urlencoded; charset=UTF-8",
            accepts: {
                "*": ub,
                text: "text/plain",
                html: "text/html",
                xml: "application/xml, text/xml",
                json: "application/json, text/javascript"
            },
            contents: {
                xml: /\bxml\b/,
                html: /\bhtml/,
                json: /\bjson\b/
            },
            responseFields: {
                xml: "responseXML",
                text: "responseText",
                json: "responseJSON"
            },
            converters: {
                "* text": String,
                "text html": !0,
                "text json": n.parseJSON,
                "text xml": n.parseXML
            },
            flatOptions: {
                url: !0,
                context: !0
            }
        },
        ajaxSetup: function (a, b) {
            return b ? yb(yb(a, n.ajaxSettings), b) : yb(n.ajaxSettings, a)
        },
        ajaxPrefilter: wb(sb),
        ajaxTransport: wb(tb),
        ajax: function (b, c) {
            "object" == typeof b && (c = b, b = void 0), c = c || {};
            var e, f, g, h, i, j, k, l, m = n.ajaxSetup({}, c),
                o = m.context || m,
                p = m.context && (o.nodeType || o.jquery) ? n(o) : n.event,
                q = n.Deferred(),
                r = n.Callbacks("once memory"),
                s = m.statusCode || {},
                t = {},
                u = {},
                v = 0,
                w = "canceled",
                x = {
                    readyState: 0,
                    getResponseHeader: function (a) {
                        var b;
                        if (2 === v) {
                            if (!h) {
                                h = {};
                                while (b = ob.exec(g)) h[b[1].toLowerCase()] = b[2]
                            }
                            b = h[a.toLowerCase()]
                        }
                        return null == b ? null : b
                    },
                    getAllResponseHeaders: function () {
                        return 2 === v ? g : null
                    },
                    setRequestHeader: function (a, b) {
                        var c = a.toLowerCase();
                        return v || (a = u[c] = u[c] || a, t[a] = b), this
                    },
                    overrideMimeType: function (a) {
                        return v || (m.mimeType = a), this
                    },
                    statusCode: function (a) {
                        var b;
                        if (a)
                            if (2 > v)
                                for (b in a) s[b] = [s[b], a[b]];
                            else x.always(a[x.status]);
                        return this
                    },
                    abort: function (a) {
                        var b = a || w;
                        return e && e.abort(b), z(0, b), this
                    }
                };
            if (q.promise(x).complete = r.add, x.success = x.done, x.error = x.fail, m.url = ((b || m.url || jb.href) + "").replace(mb, "").replace(rb, jb.protocol + "//"), m.type = c.method || c.type || m.method || m.type, m.dataTypes = n.trim(m.dataType || "*").toLowerCase().match(G) || [""], null == m.crossDomain) {
                j = d.createElement("a");
                try {
                    j.href = m.url, j.href = j.href, m.crossDomain = vb.protocol + "//" + vb.host != j.protocol + "//" + j.host
                } catch (y) {
                    m.crossDomain = !0
                }
            }
            if (m.data && m.processData && "string" != typeof m.data && (m.data = n.param(m.data, m.traditional)), xb(sb, m, c, x), 2 === v) return x;
            k = n.event && m.global, k && 0 === n.active++ && n.event.trigger("ajaxStart"), m.type = m.type.toUpperCase(), m.hasContent = !qb.test(m.type), f = m.url, m.hasContent || (m.data && (f = m.url += (lb.test(f) ? "&" : "?") + m.data, delete m.data), m.cache === !1 && (m.url = nb.test(f) ? f.replace(nb, "$1_=" + kb++) : f + (lb.test(f) ? "&" : "?") + "_=" + kb++)), m.ifModified && (n.lastModified[f] && x.setRequestHeader("If-Modified-Since", n.lastModified[f]), n.etag[f] && x.setRequestHeader("If-None-Match", n.etag[f])), (m.data && m.hasContent && m.contentType !== !1 || c.contentType) && x.setRequestHeader("Content-Type", m.contentType), x.setRequestHeader("Accept", m.dataTypes[0] && m.accepts[m.dataTypes[0]] ? m.accepts[m.dataTypes[0]] + ("*" !== m.dataTypes[0] ? ", " + ub + "; q=0.01" : "") : m.accepts["*"]);
            for (l in m.headers) x.setRequestHeader(l, m.headers[l]);
            if (m.beforeSend && (m.beforeSend.call(o, x, m) === !1 || 2 === v)) return x.abort();
            w = "abort";
            for (l in {
                    success: 1,
                    error: 1,
                    complete: 1
                }) x[l](m[l]);
            if (e = xb(tb, m, c, x)) {
                if (x.readyState = 1, k && p.trigger("ajaxSend", [x, m]), 2 === v) return x;
                m.async && m.timeout > 0 && (i = a.setTimeout(function () {
                    x.abort("timeout")
                }, m.timeout));
                try {
                    v = 1, e.send(t, z)
                } catch (y) {
                    if (!(2 > v)) throw y;
                    z(-1, y)
                }
            } else z(-1, "No Transport");

            function z(b, c, d, h) {
                var j, l, t, u, w, y = c;
                2 !== v && (v = 2, i && a.clearTimeout(i), e = void 0, g = h || "", x.readyState = b > 0 ? 4 : 0, j = b >= 200 && 300 > b || 304 === b, d && (u = zb(m, x, d)), u = Ab(m, u, x, j), j ? (m.ifModified && (w = x.getResponseHeader("Last-Modified"), w && (n.lastModified[f] = w), w = x.getResponseHeader("etag"), w && (n.etag[f] = w)), 204 === b || "HEAD" === m.type ? y = "nocontent" : 304 === b ? y = "notmodified" : (y = u.state, l = u.data, t = u.error, j = !t)) : (t = y, !b && y || (y = "error", 0 > b && (b = 0))), x.status = b, x.statusText = (c || y) + "", j ? q.resolveWith(o, [l, y, x]) : q.rejectWith(o, [x, y, t]), x.statusCode(s), s = void 0, k && p.trigger(j ? "ajaxSuccess" : "ajaxError", [x, m, j ? l : t]), r.fireWith(o, [x, y]), k && (p.trigger("ajaxComplete", [x, m]), --n.active || n.event.trigger("ajaxStop")))
            }
            return x
        },
        getJSON: function (a, b, c) {
            return n.get(a, b, c, "json")
        },
        getScript: function (a, b) {
            return n.get(a, void 0, b, "script")
        }
    }), n.each(["get", "post"], function (a, b) {
        n[b] = function (a, c, d, e) {
            return n.isFunction(c) && (e = e || d, d = c, c = void 0), n.ajax(n.extend({
                url: a,
                type: b,
                dataType: e,
                data: c,
                success: d
            }, n.isPlainObject(a) && a))
        }
    }), n._evalUrl = function (a) {
        return n.ajax({
            url: a,
            type: "GET",
            dataType: "script",
            async: !1,
            global: !1,
            "throws": !0
        })
    }, n.fn.extend({
        wrapAll: function (a) {
            var b;
            return n.isFunction(a) ? this.each(function (b) {
                n(this).wrapAll(a.call(this, b))
            }) : (this[0] && (b = n(a, this[0].ownerDocument).eq(0).clone(!0), this[0].parentNode && b.insertBefore(this[0]), b.map(function () {
                var a = this;
                while (a.firstElementChild) a = a.firstElementChild;
                return a
            }).append(this)), this)
        },
        wrapInner: function (a) {
            return n.isFunction(a) ? this.each(function (b) {
                n(this).wrapInner(a.call(this, b))
            }) : this.each(function () {
                var b = n(this),
                    c = b.contents();
                c.length ? c.wrapAll(a) : b.append(a)
            })
        },
        wrap: function (a) {
            var b = n.isFunction(a);
            return this.each(function (c) {
                n(this).wrapAll(b ? a.call(this, c) : a)
            })
        },
        unwrap: function () {
            return this.parent().each(function () {
                n.nodeName(this, "body") || n(this).replaceWith(this.childNodes)
            }).end()
        }
    }), n.expr.filters.hidden = function (a) {
        return !n.expr.filters.visible(a)
    }, n.expr.filters.visible = function (a) {
        return a.offsetWidth > 0 || a.offsetHeight > 0 || a.getClientRects().length > 0
    };
    var Bb = /%20/g,
        Cb = /\[\]$/,
        Db = /\r?\n/g,
        Eb = /^(?:submit|button|image|reset|file)$/i,
        Fb = /^(?:input|select|textarea|keygen)/i;

    function Gb(a, b, c, d) {
        var e;
        if (n.isArray(b)) n.each(b, function (b, e) {
            c || Cb.test(a) ? d(a, e) : Gb(a + "[" + ("object" == typeof e && null != e ? b : "") + "]", e, c, d)
        });
        else if (c || "object" !== n.type(b)) d(a, b);
        else
            for (e in b) Gb(a + "[" + e + "]", b[e], c, d)
    }
    n.param = function (a, b) {
        var c, d = [],
            e = function (a, b) {
                b = n.isFunction(b) ? b() : null == b ? "" : b, d[d.length] = encodeURIComponent(a) + "=" + encodeURIComponent(b)
            };
        if (void 0 === b && (b = n.ajaxSettings && n.ajaxSettings.traditional), n.isArray(a) || a.jquery && !n.isPlainObject(a)) n.each(a, function () {
            e(this.name, this.value)
        });
        else
            for (c in a) Gb(c, a[c], b, e);
        return d.join("&").replace(Bb, "+")
    }, n.fn.extend({
        serialize: function () {
            return n.param(this.serializeArray())
        },
        serializeArray: function () {
            return this.map(function () {
                var a = n.prop(this, "elements");
                return a ? n.makeArray(a) : this
            }).filter(function () {
                var a = this.type;
                return this.name && !n(this).is(":disabled") && Fb.test(this.nodeName) && !Eb.test(a) && (this.checked || !X.test(a))
            }).map(function (a, b) {
                var c = n(this).val();
                return null == c ? null : n.isArray(c) ? n.map(c, function (a) {
                    return {
                        name: b.name,
                        value: a.replace(Db, "\r\n")
                    }
                }) : {
                    name: b.name,
                    value: c.replace(Db, "\r\n")
                }
            }).get()
        }
    }), n.ajaxSettings.xhr = function () {
        try {
            return new a.XMLHttpRequest
        } catch (b) {}
    };
    var Hb = {
            0: 200,
            1223: 204
        },
        Ib = n.ajaxSettings.xhr();
    l.cors = !!Ib && "withCredentials" in Ib, l.ajax = Ib = !!Ib, n.ajaxTransport(function (b) {
        var c, d;
        return l.cors || Ib && !b.crossDomain ? {
            send: function (e, f) {
                var g, h = b.xhr();
                if (h.open(b.type, b.url, b.async, b.username, b.password), b.xhrFields)
                    for (g in b.xhrFields) h[g] = b.xhrFields[g];
                b.mimeType && h.overrideMimeType && h.overrideMimeType(b.mimeType), b.crossDomain || e["X-Requested-With"] || (e["X-Requested-With"] = "XMLHttpRequest");
                for (g in e) h.setRequestHeader(g, e[g]);
                c = function (a) {
                    return function () {
                        c && (c = d = h.onload = h.onerror = h.onabort = h.onreadystatechange = null, "abort" === a ? h.abort() : "error" === a ? "number" != typeof h.status ? f(0, "error") : f(h.status, h.statusText) : f(Hb[h.status] || h.status, h.statusText, "text" !== (h.responseType || "text") || "string" != typeof h.responseText ? {
                            binary: h.response
                        } : {
                            text: h.responseText
                        }, h.getAllResponseHeaders()))
                    }
                }, h.onload = c(), d = h.onerror = c("error"), void 0 !== h.onabort ? h.onabort = d : h.onreadystatechange = function () {
                    4 === h.readyState && a.setTimeout(function () {
                        c && d()
                    })
                }, c = c("abort");
                try {
                    h.send(b.hasContent && b.data || null)
                } catch (i) {
                    if (c) throw i
                }
            },
            abort: function () {
                c && c()
            }
        } : void 0
    }), n.ajaxSetup({
        accepts: {
            script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
        },
        contents: {
            script: /\b(?:java|ecma)script\b/
        },
        converters: {
            "text script": function (a) {
                return n.globalEval(a), a
            }
        }
    }), n.ajaxPrefilter("script", function (a) {
        void 0 === a.cache && (a.cache = !1), a.crossDomain && (a.type = "GET")
    }), n.ajaxTransport("script", function (a) {
        if (a.crossDomain) {
            var b, c;
            return {
                send: function (e, f) {
                    b = n("<script>").prop({
                        charset: a.scriptCharset,
                        src: a.url
                    }).on("load error", c = function (a) {
                        b.remove(), c = null, a && f("error" === a.type ? 404 : 200, a.type)
                    }), d.head.appendChild(b[0])
                },
                abort: function () {
                    c && c()
                }
            }
        }
    });
    var Jb = [],
        Kb = /(=)\?(?=&|$)|\?\?/;
    n.ajaxSetup({
        jsonp: "callback",
        jsonpCallback: function () {
            var a = Jb.pop() || n.expando + "_" + kb++;
            return this[a] = !0, a
        }
    }), n.ajaxPrefilter("json jsonp", function (b, c, d) {
        var e, f, g, h = b.jsonp !== !1 && (Kb.test(b.url) ? "url" : "string" == typeof b.data && 0 === (b.contentType || "").indexOf("application/x-www-form-urlencoded") && Kb.test(b.data) && "data");
        return h || "jsonp" === b.dataTypes[0] ? (e = b.jsonpCallback = n.isFunction(b.jsonpCallback) ? b.jsonpCallback() : b.jsonpCallback, h ? b[h] = b[h].replace(Kb, "$1" + e) : b.jsonp !== !1 && (b.url += (lb.test(b.url) ? "&" : "?") + b.jsonp + "=" + e), b.converters["script json"] = function () {
            return g || n.error(e + " was not called"), g[0]
        }, b.dataTypes[0] = "json", f = a[e], a[e] = function () {
            g = arguments
        }, d.always(function () {
            void 0 === f ? n(a).removeProp(e) : a[e] = f, b[e] && (b.jsonpCallback = c.jsonpCallback, Jb.push(e)), g && n.isFunction(f) && f(g[0]), g = f = void 0
        }), "script") : void 0
    }), n.parseHTML = function (a, b, c) {
        if (!a || "string" != typeof a) return null;
        "boolean" == typeof b && (c = b, b = !1), b = b || d;
        var e = x.exec(a),
            f = !c && [];
        return e ? [b.createElement(e[1])] : (e = ca([a], b, f), f && f.length && n(f).remove(), n.merge([], e.childNodes))
    };
    var Lb = n.fn.load;
    n.fn.load = function (a, b, c) {
        if ("string" != typeof a && Lb) return Lb.apply(this, arguments);
        var d, e, f, g = this,
            h = a.indexOf(" ");
        return h > -1 && (d = n.trim(a.slice(h)), a = a.slice(0, h)), n.isFunction(b) ? (c = b, b = void 0) : b && "object" == typeof b && (e = "POST"), g.length > 0 && n.ajax({
            url: a,
            type: e || "GET",
            dataType: "html",
            data: b
        }).done(function (a) {
            f = arguments, g.html(d ? n("<div>").append(n.parseHTML(a)).find(d) : a)
        }).always(c && function (a, b) {
            g.each(function () {
                c.apply(this, f || [a.responseText, b, a])
            })
        }), this
    }, n.each(["ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend"], function (a, b) {
        n.fn[b] = function (a) {
            return this.on(b, a)
        }
    }), n.expr.filters.animated = function (a) {
        return n.grep(n.timers, function (b) {
            return a === b.elem
        }).length
    };

    function Mb(a) {
        return n.isWindow(a) ? a : 9 === a.nodeType && a.defaultView
    }
    n.offset = {
        setOffset: function (a, b, c) {
            var d, e, f, g, h, i, j, k = n.css(a, "position"),
                l = n(a),
                m = {};
            "static" === k && (a.style.position = "relative"), h = l.offset(), f = n.css(a, "top"), i = n.css(a, "left"), j = ("absolute" === k || "fixed" === k) && (f + i).indexOf("auto") > -1, j ? (d = l.position(), g = d.top, e = d.left) : (g = parseFloat(f) || 0, e = parseFloat(i) || 0), n.isFunction(b) && (b = b.call(a, c, n.extend({}, h))), null != b.top && (m.top = b.top - h.top + g), null != b.left && (m.left = b.left - h.left + e), "using" in b ? b.using.call(a, m) : l.css(m)
        }
    }, n.fn.extend({
        offset: function (a) {
            if (arguments.length) return void 0 === a ? this : this.each(function (b) {
                n.offset.setOffset(this, a, b)
            });
            var b, c, d = this[0],
                e = {
                    top: 0,
                    left: 0
                },
                f = d && d.ownerDocument;
            if (f) return b = f.documentElement, n.contains(b, d) ? (e = d.getBoundingClientRect(), c = Mb(f), {
                top: e.top + c.pageYOffset - b.clientTop,
                left: e.left + c.pageXOffset - b.clientLeft
            }) : e
        },
        position: function () {
            if (this[0]) {
                var a, b, c = this[0],
                    d = {
                        top: 0,
                        left: 0
                    };
                return "fixed" === n.css(c, "position") ? b = c.getBoundingClientRect() : (a = this.offsetParent(), b = this.offset(), n.nodeName(a[0], "html") || (d = a.offset()), d.top += n.css(a[0], "borderTopWidth", !0), d.left += n.css(a[0], "borderLeftWidth", !0)), {
                    top: b.top - d.top - n.css(c, "marginTop", !0),
                    left: b.left - d.left - n.css(c, "marginLeft", !0)
                }
            }
        },
        offsetParent: function () {
            return this.map(function () {
                var a = this.offsetParent;
                while (a && "static" === n.css(a, "position")) a = a.offsetParent;
                return a || Ea
            })
        }
    }), n.each({
        scrollLeft: "pageXOffset",
        scrollTop: "pageYOffset"
    }, function (a, b) {
        var c = "pageYOffset" === b;
        n.fn[a] = function (d) {
            return K(this, function (a, d, e) {
                var f = Mb(a);
                return void 0 === e ? f ? f[b] : a[d] : void(f ? f.scrollTo(c ? f.pageXOffset : e, c ? e : f.pageYOffset) : a[d] = e)
            }, a, d, arguments.length)
        }
    }), n.each(["top", "left"], function (a, b) {
        n.cssHooks[b] = Ga(l.pixelPosition, function (a, c) {
            return c ? (c = Fa(a, b), Ba.test(c) ? n(a).position()[b] + "px" : c) : void 0
        })
    }), n.each({
        Height: "height",
        Width: "width"
    }, function (a, b) {
        n.each({
            padding: "inner" + a,
            content: b,
            "": "outer" + a
        }, function (c, d) {
            n.fn[d] = function (d, e) {
                var f = arguments.length && (c || "boolean" != typeof d),
                    g = c || (d === !0 || e === !0 ? "margin" : "border");
                return K(this, function (b, c, d) {
                    var e;
                    return n.isWindow(b) ? b.document.documentElement["client" + a] : 9 === b.nodeType ? (e = b.documentElement, Math.max(b.body["scroll" + a], e["scroll" + a], b.body["offset" + a], e["offset" + a], e["client" + a])) : void 0 === d ? n.css(b, c, g) : n.style(b, c, d, g)
                }, b, f ? d : void 0, f, null)
            }
        })
    }), n.fn.extend({
        bind: function (a, b, c) {
            return this.on(a, null, b, c)
        },
        unbind: function (a, b) {
            return this.off(a, null, b)
        },
        delegate: function (a, b, c, d) {
            return this.on(b, a, c, d)
        },
        undelegate: function (a, b, c) {
            return 1 === arguments.length ? this.off(a, "**") : this.off(b, a || "**", c)
        },
        size: function () {
            return this.length
        }
    }), n.fn.andSelf = n.fn.addBack, "function" == typeof define && define.amd && define("jquery", [], function () {
        return n
    });
    var Nb = a.jQuery,
        Ob = a.$;
    return n.noConflict = function (b) {
        return a.$ === n && (a.$ = Ob), b && a.jQuery === n && (a.jQuery = Nb), n
    }, b || (a.jQuery = a.$ = n), n
});

/*!
 * Bootstrap v3.3.7 (http://getbootstrap.com)
 * Copyright 2011-2016 Twitter, Inc.
 * Licensed under the MIT license
 */
if ("undefined" == typeof jQuery) throw new Error("Bootstrap's JavaScript requires jQuery"); + function (a) {
    "use strict";
    var b = a.fn.jquery.split(" ")[0].split(".");
    if (b[0] < 2 && b[1] < 9 || 1 == b[0] && 9 == b[1] && b[2] < 1 || b[0] > 3) throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4")
}(jQuery), + function (a) {
    "use strict";

    function b() {
        var a = document.createElement("bootstrap"),
            b = {
                WebkitTransition: "webkitTransitionEnd",
                MozTransition: "transitionend",
                OTransition: "oTransitionEnd otransitionend",
                transition: "transitionend"
            };
        for (var c in b)
            if (void 0 !== a.style[c]) return {
                end: b[c]
            };
        return !1
    }
    a.fn.emulateTransitionEnd = function (b) {
        var c = !1,
            d = this;
        a(this).one("bsTransitionEnd", function () {
            c = !0
        });
        var e = function () {
            c || a(d).trigger(a.support.transition.end)
        };
        return setTimeout(e, b), this
    }, a(function () {
        a.support.transition = b(), a.support.transition && (a.event.special.bsTransitionEnd = {
            bindType: a.support.transition.end,
            delegateType: a.support.transition.end,
            handle: function (b) {
                if (a(b.target).is(this)) return b.handleObj.handler.apply(this, arguments)
            }
        })
    })
}(jQuery), + function (a) {
    "use strict";

    function b(b) {
        return this.each(function () {
            var c = a(this),
                e = c.data("bs.alert");
            e || c.data("bs.alert", e = new d(this)), "string" == typeof b && e[b].call(c)
        })
    }
    var c = '[data-dismiss="alert"]',
        d = function (b) {
            a(b).on("click", c, this.close)
        };
    d.VERSION = "3.3.7", d.TRANSITION_DURATION = 150, d.prototype.close = function (b) {
        function c() {
            g.detach().trigger("closed.bs.alert").remove()
        }
        var e = a(this),
            f = e.attr("data-target");
        f || (f = e.attr("href"), f = f && f.replace(/.*(?=#[^\s]*$)/, ""));
        var g = a("#" === f ? [] : f);
        b && b.preventDefault(), g.length || (g = e.closest(".alert")), g.trigger(b = a.Event("close.bs.alert")), b.isDefaultPrevented() || (g.removeClass("in"), a.support.transition && g.hasClass("fade") ? g.one("bsTransitionEnd", c).emulateTransitionEnd(d.TRANSITION_DURATION) : c())
    };
    var e = a.fn.alert;
    a.fn.alert = b, a.fn.alert.Constructor = d, a.fn.alert.noConflict = function () {
        return a.fn.alert = e, this
    }, a(document).on("click.bs.alert.data-api", c, d.prototype.close)
}(jQuery), + function (a) {
    "use strict";

    function b(b) {
        return this.each(function () {
            var d = a(this),
                e = d.data("bs.button"),
                f = "object" == typeof b && b;
            e || d.data("bs.button", e = new c(this, f)), "toggle" == b ? e.toggle() : b && e.setState(b)
        })
    }
    var c = function (b, d) {
        this.$element = a(b), this.options = a.extend({}, c.DEFAULTS, d), this.isLoading = !1
    };
    c.VERSION = "3.3.7", c.DEFAULTS = {
        loadingText: "loading..."
    }, c.prototype.setState = function (b) {
        var c = "disabled",
            d = this.$element,
            e = d.is("input") ? "val" : "html",
            f = d.data();
        b += "Text", null == f.resetText && d.data("resetText", d[e]()), setTimeout(a.proxy(function () {
            d[e](null == f[b] ? this.options[b] : f[b]), "loadingText" == b ? (this.isLoading = !0, d.addClass(c).attr(c, c).prop(c, !0)) : this.isLoading && (this.isLoading = !1, d.removeClass(c).removeAttr(c).prop(c, !1))
        }, this), 0)
    }, c.prototype.toggle = function () {
        var a = !0,
            b = this.$element.closest('[data-toggle="buttons"]');
        if (b.length) {
            var c = this.$element.find("input");
            "radio" == c.prop("type") ? (c.prop("checked") && (a = !1), b.find(".active").removeClass("active"), this.$element.addClass("active")) : "checkbox" == c.prop("type") && (c.prop("checked") !== this.$element.hasClass("active") && (a = !1), this.$element.toggleClass("active")), c.prop("checked", this.$element.hasClass("active")), a && c.trigger("change")
        } else this.$element.attr("aria-pressed", !this.$element.hasClass("active")), this.$element.toggleClass("active")
    };
    var d = a.fn.button;
    a.fn.button = b, a.fn.button.Constructor = c, a.fn.button.noConflict = function () {
        return a.fn.button = d, this
    }, a(document).on("click.bs.button.data-api", '[data-toggle^="button"]', function (c) {
        var d = a(c.target).closest(".btn");
        b.call(d, "toggle"), a(c.target).is('input[type="radio"], input[type="checkbox"]') || (c.preventDefault(), d.is("input,button") ? d.trigger("focus") : d.find("input:visible,button:visible").first().trigger("focus"))
    }).on("focus.bs.button.data-api blur.bs.button.data-api", '[data-toggle^="button"]', function (b) {
        a(b.target).closest(".btn").toggleClass("focus", /^focus(in)?$/.test(b.type))
    })
}(jQuery), + function (a) {
    "use strict";

    function b(b) {
        return this.each(function () {
            var d = a(this),
                e = d.data("bs.carousel"),
                f = a.extend({}, c.DEFAULTS, d.data(), "object" == typeof b && b),
                g = "string" == typeof b ? b : f.slide;
            e || d.data("bs.carousel", e = new c(this, f)), "number" == typeof b ? e.to(b) : g ? e[g]() : f.interval && e.pause().cycle()
        })
    }
    var c = function (b, c) {
        this.$element = a(b), this.$indicators = this.$element.find(".carousel-indicators"), this.options = c, this.paused = null, this.sliding = null, this.interval = null, this.$active = null, this.$items = null, this.options.keyboard && this.$element.on("keydown.bs.carousel", a.proxy(this.keydown, this)), "hover" == this.options.pause && !("ontouchstart" in document.documentElement) && this.$element.on("mouseenter.bs.carousel", a.proxy(this.pause, this)).on("mouseleave.bs.carousel", a.proxy(this.cycle, this))
    };
    c.VERSION = "3.3.7", c.TRANSITION_DURATION = 600, c.DEFAULTS = {
        interval: 5e3,
        pause: "hover",
        wrap: !0,
        keyboard: !0
    }, c.prototype.keydown = function (a) {
        if (!/input|textarea/i.test(a.target.tagName)) {
            switch (a.which) {
                case 37:
                    this.prev();
                    break;
                case 39:
                    this.next();
                    break;
                default:
                    return
            }
            a.preventDefault()
        }
    }, c.prototype.cycle = function (b) {
        return b || (this.paused = !1), this.interval && clearInterval(this.interval), this.options.interval && !this.paused && (this.interval = setInterval(a.proxy(this.next, this), this.options.interval)), this
    }, c.prototype.getItemIndex = function (a) {
        return this.$items = a.parent().children(".item"), this.$items.index(a || this.$active)
    }, c.prototype.getItemForDirection = function (a, b) {
        var c = this.getItemIndex(b),
            d = "prev" == a && 0 === c || "next" == a && c == this.$items.length - 1;
        if (d && !this.options.wrap) return b;
        var e = "prev" == a ? -1 : 1,
            f = (c + e) % this.$items.length;
        return this.$items.eq(f)
    }, c.prototype.to = function (a) {
        var b = this,
            c = this.getItemIndex(this.$active = this.$element.find(".item.active"));
        if (!(a > this.$items.length - 1 || a < 0)) return this.sliding ? this.$element.one("slid.bs.carousel", function () {
            b.to(a)
        }) : c == a ? this.pause().cycle() : this.slide(a > c ? "next" : "prev", this.$items.eq(a))
    }, c.prototype.pause = function (b) {
        return b || (this.paused = !0), this.$element.find(".next, .prev").length && a.support.transition && (this.$element.trigger(a.support.transition.end), this.cycle(!0)), this.interval = clearInterval(this.interval), this
    }, c.prototype.next = function () {
        if (!this.sliding) return this.slide("next")
    }, c.prototype.prev = function () {
        if (!this.sliding) return this.slide("prev")
    }, c.prototype.slide = function (b, d) {
        var e = this.$element.find(".item.active"),
            f = d || this.getItemForDirection(b, e),
            g = this.interval,
            h = "next" == b ? "left" : "right",
            i = this;
        if (f.hasClass("active")) return this.sliding = !1;
        var j = f[0],
            k = a.Event("slide.bs.carousel", {
                relatedTarget: j,
                direction: h
            });
        if (this.$element.trigger(k), !k.isDefaultPrevented()) {
            if (this.sliding = !0, g && this.pause(), this.$indicators.length) {
                this.$indicators.find(".active").removeClass("active");
                var l = a(this.$indicators.children()[this.getItemIndex(f)]);
                l && l.addClass("active")
            }
            var m = a.Event("slid.bs.carousel", {
                relatedTarget: j,
                direction: h
            });
            return a.support.transition && this.$element.hasClass("slide") ? (f.addClass(b), f[0].offsetWidth, e.addClass(h), f.addClass(h), e.one("bsTransitionEnd", function () {
                f.removeClass([b, h].join(" ")).addClass("active"), e.removeClass(["active", h].join(" ")), i.sliding = !1, setTimeout(function () {
                    i.$element.trigger(m)
                }, 0)
            }).emulateTransitionEnd(c.TRANSITION_DURATION)) : (e.removeClass("active"), f.addClass("active"), this.sliding = !1, this.$element.trigger(m)), g && this.cycle(), this
        }
    };
    var d = a.fn.carousel;
    a.fn.carousel = b, a.fn.carousel.Constructor = c, a.fn.carousel.noConflict = function () {
        return a.fn.carousel = d, this
    };
    var e = function (c) {
        var d, e = a(this),
            f = a(e.attr("data-target") || (d = e.attr("href")) && d.replace(/.*(?=#[^\s]+$)/, ""));
        if (f.hasClass("carousel")) {
            var g = a.extend({}, f.data(), e.data()),
                h = e.attr("data-slide-to");
            h && (g.interval = !1), b.call(f, g), h && f.data("bs.carousel").to(h), c.preventDefault()
        }
    };
    a(document).on("click.bs.carousel.data-api", "[data-slide]", e).on("click.bs.carousel.data-api", "[data-slide-to]", e), a(window).on("load", function () {
        a('[data-ride="carousel"]').each(function () {
            var c = a(this);
            b.call(c, c.data())
        })
    })
}(jQuery), + function (a) {
    "use strict";

    function b(b) {
        var c, d = b.attr("data-target") || (c = b.attr("href")) && c.replace(/.*(?=#[^\s]+$)/, "");
        return a(d)
    }

    function c(b) {
        return this.each(function () {
            var c = a(this),
                e = c.data("bs.collapse"),
                f = a.extend({}, d.DEFAULTS, c.data(), "object" == typeof b && b);
            !e && f.toggle && /show|hide/.test(b) && (f.toggle = !1), e || c.data("bs.collapse", e = new d(this, f)), "string" == typeof b && e[b]()
        })
    }
    var d = function (b, c) {
        this.$element = a(b), this.options = a.extend({}, d.DEFAULTS, c), this.$trigger = a('[data-toggle="collapse"][href="#' + b.id + '"],[data-toggle="collapse"][data-target="#' + b.id + '"]'), this.transitioning = null, this.options.parent ? this.$parent = this.getParent() : this.addAriaAndCollapsedClass(this.$element, this.$trigger), this.options.toggle && this.toggle()
    };
    d.VERSION = "3.3.7", d.TRANSITION_DURATION = 350, d.DEFAULTS = {
        toggle: !0
    }, d.prototype.dimension = function () {
        var a = this.$element.hasClass("width");
        return a ? "width" : "height"
    }, d.prototype.show = function () {
        if (!this.transitioning && !this.$element.hasClass("in")) {
            var b, e = this.$parent && this.$parent.children(".panel").children(".in, .collapsing");
            if (!(e && e.length && (b = e.data("bs.collapse"), b && b.transitioning))) {
                var f = a.Event("show.bs.collapse");
                if (this.$element.trigger(f), !f.isDefaultPrevented()) {
                    e && e.length && (c.call(e, "hide"), b || e.data("bs.collapse", null));
                    var g = this.dimension();
                    this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded", !0), this.$trigger.removeClass("collapsed").attr("aria-expanded", !0), this.transitioning = 1;
                    var h = function () {
                        this.$element.removeClass("collapsing").addClass("collapse in")[g](""), this.transitioning = 0, this.$element.trigger("shown.bs.collapse")
                    };
                    if (!a.support.transition) return h.call(this);
                    var i = a.camelCase(["scroll", g].join("-"));
                    this.$element.one("bsTransitionEnd", a.proxy(h, this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])
                }
            }
        }
    }, d.prototype.hide = function () {
        if (!this.transitioning && this.$element.hasClass("in")) {
            var b = a.Event("hide.bs.collapse");
            if (this.$element.trigger(b), !b.isDefaultPrevented()) {
                var c = this.dimension();
                this.$element[c](this.$element[c]())[0].offsetHeight, this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded", !1), this.$trigger.addClass("collapsed").attr("aria-expanded", !1), this.transitioning = 1;
                var e = function () {
                    this.transitioning = 0, this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")
                };
                return a.support.transition ? void this.$element[c](0).one("bsTransitionEnd", a.proxy(e, this)).emulateTransitionEnd(d.TRANSITION_DURATION) : e.call(this)
            }
        }
    }, d.prototype.toggle = function () {
        this[this.$element.hasClass("in") ? "hide" : "show"]()
    }, d.prototype.getParent = function () {
        return a(this.options.parent).find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]').each(a.proxy(function (c, d) {
            var e = a(d);
            this.addAriaAndCollapsedClass(b(e), e)
        }, this)).end()
    }, d.prototype.addAriaAndCollapsedClass = function (a, b) {
        var c = a.hasClass("in");
        a.attr("aria-expanded", c), b.toggleClass("collapsed", !c).attr("aria-expanded", c)
    };
    var e = a.fn.collapse;
    a.fn.collapse = c, a.fn.collapse.Constructor = d, a.fn.collapse.noConflict = function () {
        return a.fn.collapse = e, this
    }, a(document).on("click.bs.collapse.data-api", '[data-toggle="collapse"]', function (d) {
        var e = a(this);
        e.attr("data-target") || d.preventDefault();
        var f = b(e),
            g = f.data("bs.collapse"),
            h = g ? "toggle" : e.data();
        c.call(f, h)
    })
}(jQuery), + function (a) {
    "use strict";

    function b(b) {
        var c = b.attr("data-target");
        c || (c = b.attr("href"), c = c && /#[A-Za-z]/.test(c) && c.replace(/.*(?=#[^\s]*$)/, ""));
        var d = c && a(c);
        return d && d.length ? d : b.parent()
    }

    function c(c) {
        c && 3 === c.which || (a(e).remove(), a(f).each(function () {
            var d = a(this),
                e = b(d),
                f = {
                    relatedTarget: this
                };
            e.hasClass("open") && (c && "click" == c.type && /input|textarea/i.test(c.target.tagName) && a.contains(e[0], c.target) || (e.trigger(c = a.Event("hide.bs.dropdown", f)), c.isDefaultPrevented() || (d.attr("aria-expanded", "false"), e.removeClass("open").trigger(a.Event("hidden.bs.dropdown", f)))))
        }))
    }

    function d(b) {
        return this.each(function () {
            var c = a(this),
                d = c.data("bs.dropdown");
            d || c.data("bs.dropdown", d = new g(this)), "string" == typeof b && d[b].call(c)
        })
    }
    var e = ".dropdown-backdrop",
        f = '[data-toggle="dropdown"]',
        g = function (b) {
            a(b).on("click.bs.dropdown", this.toggle)
        };
    g.VERSION = "3.3.7", g.prototype.toggle = function (d) {
        var e = a(this);
        if (!e.is(".disabled, :disabled")) {
            var f = b(e),
                g = f.hasClass("open");
            if (c(), !g) {
                "ontouchstart" in document.documentElement && !f.closest(".navbar-nav").length && a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click", c);
                var h = {
                    relatedTarget: this
                };
                if (f.trigger(d = a.Event("show.bs.dropdown", h)), d.isDefaultPrevented()) return;
                e.trigger("focus").attr("aria-expanded", "true"), f.toggleClass("open").trigger(a.Event("shown.bs.dropdown", h))
            }
            return !1
        }
    }, g.prototype.keydown = function (c) {
        if (/(38|40|27|32)/.test(c.which) && !/input|textarea/i.test(c.target.tagName)) {
            var d = a(this);
            if (c.preventDefault(), c.stopPropagation(), !d.is(".disabled, :disabled")) {
                var e = b(d),
                    g = e.hasClass("open");
                if (!g && 27 != c.which || g && 27 == c.which) return 27 == c.which && e.find(f).trigger("focus"), d.trigger("click");
                var h = " li:not(.disabled):visible a",
                    i = e.find(".dropdown-menu" + h);
                if (i.length) {
                    var j = i.index(c.target);
                    38 == c.which && j > 0 && j--, 40 == c.which && j < i.length - 1 && j++, ~j || (j = 0), i.eq(j).trigger("focus")
                }
            }
        }
    };
    var h = a.fn.dropdown;
    a.fn.dropdown = d, a.fn.dropdown.Constructor = g, a.fn.dropdown.noConflict = function () {
        return a.fn.dropdown = h, this
    }, a(document).on("click.bs.dropdown.data-api", c).on("click.bs.dropdown.data-api", ".dropdown form", function (a) {
        a.stopPropagation()
    }).on("click.bs.dropdown.data-api", f, g.prototype.toggle).on("keydown.bs.dropdown.data-api", f, g.prototype.keydown).on("keydown.bs.dropdown.data-api", ".dropdown-menu", g.prototype.keydown)
}(jQuery), + function (a) {
    "use strict";

    function b(b, d) {
        return this.each(function () {
            var e = a(this),
                f = e.data("bs.modal"),
                g = a.extend({}, c.DEFAULTS, e.data(), "object" == typeof b && b);
            f || e.data("bs.modal", f = new c(this, g)), "string" == typeof b ? f[b](d) : g.show && f.show(d)
        })
    }
    var c = function (b, c) {
        this.options = c, this.$body = a(document.body), this.$element = a(b), this.$dialog = this.$element.find(".modal-dialog"), this.$backdrop = null, this.isShown = null, this.originalBodyPad = null, this.scrollbarWidth = 0, this.ignoreBackdropClick = !1, this.options.remote && this.$element.find(".modal-content").load(this.options.remote, a.proxy(function () {
            this.$element.trigger("loaded.bs.modal")
        }, this))
    };
    c.VERSION = "3.3.7", c.TRANSITION_DURATION = 300, c.BACKDROP_TRANSITION_DURATION = 150, c.DEFAULTS = {
        backdrop: !0,
        keyboard: !0,
        show: !0
    }, c.prototype.toggle = function (a) {
        return this.isShown ? this.hide() : this.show(a)
    }, c.prototype.show = function (b) {
        var d = this,
            e = a.Event("show.bs.modal", {
                relatedTarget: b
            });
        this.$element.trigger(e), this.isShown || e.isDefaultPrevented() || (this.isShown = !0, this.checkScrollbar(), this.setScrollbar(), this.$body.addClass("modal-open"), this.escape(), this.resize(), this.$element.on("click.dismiss.bs.modal", '[data-dismiss="modal"]', a.proxy(this.hide, this)), this.$dialog.on("mousedown.dismiss.bs.modal", function () {
            d.$element.one("mouseup.dismiss.bs.modal", function (b) {
                a(b.target).is(d.$element) && (d.ignoreBackdropClick = !0)
            })
        }), this.backdrop(function () {
            var e = a.support.transition && d.$element.hasClass("fade");
            d.$element.parent().length || d.$element.appendTo(d.$body), d.$element.show().scrollTop(0), d.adjustDialog(), e && d.$element[0].offsetWidth, d.$element.addClass("in"), d.enforceFocus();
            var f = a.Event("shown.bs.modal", {
                relatedTarget: b
            });
            e ? d.$dialog.one("bsTransitionEnd", function () {
                d.$element.trigger("focus").trigger(f)
            }).emulateTransitionEnd(c.TRANSITION_DURATION) : d.$element.trigger("focus").trigger(f)
        }))
    }, c.prototype.hide = function (b) {
        b && b.preventDefault(), b = a.Event("hide.bs.modal"), this.$element.trigger(b), this.isShown && !b.isDefaultPrevented() && (this.isShown = !1, this.escape(), this.resize(), a(document).off("focusin.bs.modal"), this.$element.removeClass("in").off("click.dismiss.bs.modal").off("mouseup.dismiss.bs.modal"), this.$dialog.off("mousedown.dismiss.bs.modal"), a.support.transition && this.$element.hasClass("fade") ? this.$element.one("bsTransitionEnd", a.proxy(this.hideModal, this)).emulateTransitionEnd(c.TRANSITION_DURATION) : this.hideModal())
    }, c.prototype.enforceFocus = function () {
        a(document).off("focusin.bs.modal").on("focusin.bs.modal", a.proxy(function (a) {
            document === a.target || this.$element[0] === a.target || this.$element.has(a.target).length || this.$element.trigger("focus")
        }, this))
    }, c.prototype.escape = function () {
        this.isShown && this.options.keyboard ? this.$element.on("keydown.dismiss.bs.modal", a.proxy(function (a) {
            27 == a.which && this.hide()
        }, this)) : this.isShown || this.$element.off("keydown.dismiss.bs.modal")
    }, c.prototype.resize = function () {
        this.isShown ? a(window).on("resize.bs.modal", a.proxy(this.handleUpdate, this)) : a(window).off("resize.bs.modal")
    }, c.prototype.hideModal = function () {
        var a = this;
        this.$element.hide(), this.backdrop(function () {
            a.$body.removeClass("modal-open"), a.resetAdjustments(), a.resetScrollbar(), a.$element.trigger("hidden.bs.modal")
        })
    }, c.prototype.removeBackdrop = function () {
        this.$backdrop && this.$backdrop.remove(), this.$backdrop = null
    }, c.prototype.backdrop = function (b) {
        var d = this,
            e = this.$element.hasClass("fade") ? "fade" : "";
        if (this.isShown && this.options.backdrop) {
            var f = a.support.transition && e;
            if (this.$backdrop = a(document.createElement("div")).addClass("modal-backdrop " + e).appendTo(this.$body), this.$element.on("click.dismiss.bs.modal", a.proxy(function (a) {
                    return this.ignoreBackdropClick ? void(this.ignoreBackdropClick = !1) : void(a.target === a.currentTarget && ("static" == this.options.backdrop ? this.$element[0].focus() : this.hide()))
                }, this)), f && this.$backdrop[0].offsetWidth, this.$backdrop.addClass("in"), !b) return;
            f ? this.$backdrop.one("bsTransitionEnd", b).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION) : b()
        } else if (!this.isShown && this.$backdrop) {
            this.$backdrop.removeClass("in");
            var g = function () {
                d.removeBackdrop(), b && b()
            };
            a.support.transition && this.$element.hasClass("fade") ? this.$backdrop.one("bsTransitionEnd", g).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION) : g()
        } else b && b()
    }, c.prototype.handleUpdate = function () {
        this.adjustDialog()
    }, c.prototype.adjustDialog = function () {
        var a = this.$element[0].scrollHeight > document.documentElement.clientHeight;
        this.$element.css({
            paddingLeft: !this.bodyIsOverflowing && a ? this.scrollbarWidth : "",
            paddingRight: this.bodyIsOverflowing && !a ? this.scrollbarWidth : ""
        })
    }, c.prototype.resetAdjustments = function () {
        this.$element.css({
            paddingLeft: "",
            paddingRight: ""
        })
    }, c.prototype.checkScrollbar = function () {
        var a = window.innerWidth;
        if (!a) {
            var b = document.documentElement.getBoundingClientRect();
            a = b.right - Math.abs(b.left)
        }
        this.bodyIsOverflowing = document.body.clientWidth < a, this.scrollbarWidth = this.measureScrollbar()
    }, c.prototype.setScrollbar = function () {
        var a = parseInt(this.$body.css("padding-right") || 0, 10);
        this.originalBodyPad = document.body.style.paddingRight || "", this.bodyIsOverflowing && this.$body.css("padding-right", a + this.scrollbarWidth)
    }, c.prototype.resetScrollbar = function () {
        this.$body.css("padding-right", this.originalBodyPad)
    }, c.prototype.measureScrollbar = function () {
        var a = document.createElement("div");
        a.className = "modal-scrollbar-measure", this.$body.append(a);
        var b = a.offsetWidth - a.clientWidth;
        return this.$body[0].removeChild(a), b
    };
    var d = a.fn.modal;
    a.fn.modal = b, a.fn.modal.Constructor = c, a.fn.modal.noConflict = function () {
        return a.fn.modal = d, this
    }, a(document).on("click.bs.modal.data-api", '[data-toggle="modal"]', function (c) {
        var d = a(this),
            e = d.attr("href"),
            f = a(d.attr("data-target") || e && e.replace(/.*(?=#[^\s]+$)/, "")),
            g = f.data("bs.modal") ? "toggle" : a.extend({
                remote: !/#/.test(e) && e
            }, f.data(), d.data());
        d.is("a") && c.preventDefault(), f.one("show.bs.modal", function (a) {
            a.isDefaultPrevented() || f.one("hidden.bs.modal", function () {
                d.is(":visible") && d.trigger("focus")
            })
        }), b.call(f, g, this)
    })
}(jQuery), + function (a) {
    "use strict";

    function b(b) {
        return this.each(function () {
            var d = a(this),
                e = d.data("bs.tooltip"),
                f = "object" == typeof b && b;
            !e && /destroy|hide/.test(b) || (e || d.data("bs.tooltip", e = new c(this, f)), "string" == typeof b && e[b]())
        })
    }
    var c = function (a, b) {
        this.type = null, this.options = null, this.enabled = null, this.timeout = null, this.hoverState = null, this.$element = null, this.inState = null, this.init("tooltip", a, b)
    };
    c.VERSION = "3.3.7", c.TRANSITION_DURATION = 150, c.DEFAULTS = {
        animation: !0,
        placement: "top",
        selector: !1,
        template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
        trigger: "hover focus",
        title: "",
        delay: 0,
        html: !1,
        container: !1,
        viewport: {
            selector: "body",
            padding: 0
        }
    }, c.prototype.init = function (b, c, d) {
        if (this.enabled = !0, this.type = b, this.$element = a(c), this.options = this.getOptions(d), this.$viewport = this.options.viewport && a(a.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : this.options.viewport.selector || this.options.viewport), this.inState = {
                click: !1,
                hover: !1,
                focus: !1
            }, this.$element[0] instanceof document.constructor && !this.options.selector) throw new Error("`selector` option must be specified when initializing " + this.type + " on the window.document object!");
        for (var e = this.options.trigger.split(" "), f = e.length; f--;) {
            var g = e[f];
            if ("click" == g) this.$element.on("click." + this.type, this.options.selector, a.proxy(this.toggle, this));
            else if ("manual" != g) {
                var h = "hover" == g ? "mouseenter" : "focusin",
                    i = "hover" == g ? "mouseleave" : "focusout";
                this.$element.on(h + "." + this.type, this.options.selector, a.proxy(this.enter, this)), this.$element.on(i + "." + this.type, this.options.selector, a.proxy(this.leave, this))
            }
        }
        this.options.selector ? this._options = a.extend({}, this.options, {
            trigger: "manual",
            selector: ""
        }) : this.fixTitle()
    }, c.prototype.getDefaults = function () {
        return c.DEFAULTS
    }, c.prototype.getOptions = function (b) {
        return b = a.extend({}, this.getDefaults(), this.$element.data(), b), b.delay && "number" == typeof b.delay && (b.delay = {
            show: b.delay,
            hide: b.delay
        }), b
    }, c.prototype.getDelegateOptions = function () {
        var b = {},
            c = this.getDefaults();
        return this._options && a.each(this._options, function (a, d) {
            c[a] != d && (b[a] = d)
        }), b
    }, c.prototype.enter = function (b) {
        var c = b instanceof this.constructor ? b : a(b.currentTarget).data("bs." + this.type);
        return c || (c = new this.constructor(b.currentTarget, this.getDelegateOptions()), a(b.currentTarget).data("bs." + this.type, c)), b instanceof a.Event && (c.inState["focusin" == b.type ? "focus" : "hover"] = !0), c.tip().hasClass("in") || "in" == c.hoverState ? void(c.hoverState = "in") : (clearTimeout(c.timeout), c.hoverState = "in", c.options.delay && c.options.delay.show ? void(c.timeout = setTimeout(function () {
            "in" == c.hoverState && c.show()
        }, c.options.delay.show)) : c.show())
    }, c.prototype.isInStateTrue = function () {
        for (var a in this.inState)
            if (this.inState[a]) return !0;
        return !1
    }, c.prototype.leave = function (b) {
        var c = b instanceof this.constructor ? b : a(b.currentTarget).data("bs." + this.type);
        if (c || (c = new this.constructor(b.currentTarget, this.getDelegateOptions()), a(b.currentTarget).data("bs." + this.type, c)), b instanceof a.Event && (c.inState["focusout" == b.type ? "focus" : "hover"] = !1), !c.isInStateTrue()) return clearTimeout(c.timeout), c.hoverState = "out", c.options.delay && c.options.delay.hide ? void(c.timeout = setTimeout(function () {
            "out" == c.hoverState && c.hide()
        }, c.options.delay.hide)) : c.hide()
    }, c.prototype.show = function () {
        var b = a.Event("show.bs." + this.type);
        if (this.hasContent() && this.enabled) {
            this.$element.trigger(b);
            var d = a.contains(this.$element[0].ownerDocument.documentElement, this.$element[0]);
            if (b.isDefaultPrevented() || !d) return;
            var e = this,
                f = this.tip(),
                g = this.getUID(this.type);
            this.setContent(), f.attr("id", g), this.$element.attr("aria-describedby", g), this.options.animation && f.addClass("fade");
            var h = "function" == typeof this.options.placement ? this.options.placement.call(this, f[0], this.$element[0]) : this.options.placement,
                i = /\s?auto?\s?/i,
                j = i.test(h);
            j && (h = h.replace(i, "") || "top"), f.detach().css({
                top: 0,
                left: 0,
                display: "block"
            }).addClass(h).data("bs." + this.type, this), this.options.container ? f.appendTo(this.options.container) : f.insertAfter(this.$element), this.$element.trigger("inserted.bs." + this.type);
            var k = this.getPosition(),
                l = f[0].offsetWidth,
                m = f[0].offsetHeight;
            if (j) {
                var n = h,
                    o = this.getPosition(this.$viewport);
                h = "bottom" == h && k.bottom + m > o.bottom ? "top" : "top" == h && k.top - m < o.top ? "bottom" : "right" == h && k.right + l > o.width ? "left" : "left" == h && k.left - l < o.left ? "right" : h, f.removeClass(n).addClass(h)
            }
            var p = this.getCalculatedOffset(h, k, l, m);
            this.applyPlacement(p, h);
            var q = function () {
                var a = e.hoverState;
                e.$element.trigger("shown.bs." + e.type), e.hoverState = null, "out" == a && e.leave(e)
            };
            a.support.transition && this.$tip.hasClass("fade") ? f.one("bsTransitionEnd", q).emulateTransitionEnd(c.TRANSITION_DURATION) : q()
        }
    }, c.prototype.applyPlacement = function (b, c) {
        var d = this.tip(),
            e = d[0].offsetWidth,
            f = d[0].offsetHeight,
            g = parseInt(d.css("margin-top"), 10),
            h = parseInt(d.css("margin-left"), 10);
        isNaN(g) && (g = 0), isNaN(h) && (h = 0), b.top += g, b.left += h, a.offset.setOffset(d[0], a.extend({
            using: function (a) {
                d.css({
                    top: Math.round(a.top),
                    left: Math.round(a.left)
                })
            }
        }, b), 0), d.addClass("in");
        var i = d[0].offsetWidth,
            j = d[0].offsetHeight;
        "top" == c && j != f && (b.top = b.top + f - j);
        var k = this.getViewportAdjustedDelta(c, b, i, j);
        k.left ? b.left += k.left : b.top += k.top;
        var l = /top|bottom/.test(c),
            m = l ? 2 * k.left - e + i : 2 * k.top - f + j,
            n = l ? "offsetWidth" : "offsetHeight";
        d.offset(b), this.replaceArrow(m, d[0][n], l)
    }, c.prototype.replaceArrow = function (a, b, c) {
        this.arrow().css(c ? "left" : "top", 50 * (1 - a / b) + "%").css(c ? "top" : "left", "")
    }, c.prototype.setContent = function () {
        var a = this.tip(),
            b = this.getTitle();
        a.find(".tooltip-inner")[this.options.html ? "html" : "text"](b), a.removeClass("fade in top bottom left right")
    }, c.prototype.hide = function (b) {
        function d() {
            "in" != e.hoverState && f.detach(), e.$element && e.$element.removeAttr("aria-describedby").trigger("hidden.bs." + e.type), b && b()
        }
        var e = this,
            f = a(this.$tip),
            g = a.Event("hide.bs." + this.type);
        if (this.$element.trigger(g), !g.isDefaultPrevented()) return f.removeClass("in"), a.support.transition && f.hasClass("fade") ? f.one("bsTransitionEnd", d).emulateTransitionEnd(c.TRANSITION_DURATION) : d(), this.hoverState = null, this
    }, c.prototype.fixTitle = function () {
        var a = this.$element;
        (a.attr("title") || "string" != typeof a.attr("data-original-title")) && a.attr("data-original-title", a.attr("title") || "").attr("title", "")
    }, c.prototype.hasContent = function () {
        return this.getTitle()
    }, c.prototype.getPosition = function (b) {
        b = b || this.$element;
        var c = b[0],
            d = "BODY" == c.tagName,
            e = c.getBoundingClientRect();
        null == e.width && (e = a.extend({}, e, {
            width: e.right - e.left,
            height: e.bottom - e.top
        }));
        var f = window.SVGElement && c instanceof window.SVGElement,
            g = d ? {
                top: 0,
                left: 0
            } : f ? null : b.offset(),
            h = {
                scroll: d ? document.documentElement.scrollTop || document.body.scrollTop : b.scrollTop()
            },
            i = d ? {
                width: a(window).width(),
                height: a(window).height()
            } : null;
        return a.extend({}, e, h, i, g)
    }, c.prototype.getCalculatedOffset = function (a, b, c, d) {
        return "bottom" == a ? {
            top: b.top + b.height,
            left: b.left + b.width / 2 - c / 2
        } : "top" == a ? {
            top: b.top - d,
            left: b.left + b.width / 2 - c / 2
        } : "left" == a ? {
            top: b.top + b.height / 2 - d / 2,
            left: b.left - c
        } : {
            top: b.top + b.height / 2 - d / 2,
            left: b.left + b.width
        }
    }, c.prototype.getViewportAdjustedDelta = function (a, b, c, d) {
        var e = {
            top: 0,
            left: 0
        };
        if (!this.$viewport) return e;
        var f = this.options.viewport && this.options.viewport.padding || 0,
            g = this.getPosition(this.$viewport);
        if (/right|left/.test(a)) {
            var h = b.top - f - g.scroll,
                i = b.top + f - g.scroll + d;
            h < g.top ? e.top = g.top - h : i > g.top + g.height && (e.top = g.top + g.height - i)
        } else {
            var j = b.left - f,
                k = b.left + f + c;
            j < g.left ? e.left = g.left - j : k > g.right && (e.left = g.left + g.width - k)
        }
        return e
    }, c.prototype.getTitle = function () {
        var a, b = this.$element,
            c = this.options;
        return a = b.attr("data-original-title") || ("function" == typeof c.title ? c.title.call(b[0]) : c.title)
    }, c.prototype.getUID = function (a) {
        do a += ~~(1e6 * Math.random()); while (document.getElementById(a));
        return a
    }, c.prototype.tip = function () {
        if (!this.$tip && (this.$tip = a(this.options.template), 1 != this.$tip.length)) throw new Error(this.type + " `template` option must consist of exactly 1 top-level element!");
        return this.$tip
    }, c.prototype.arrow = function () {
        return this.$arrow = this.$arrow || this.tip().find(".tooltip-arrow")
    }, c.prototype.enable = function () {
        this.enabled = !0
    }, c.prototype.disable = function () {
        this.enabled = !1
    }, c.prototype.toggleEnabled = function () {
        this.enabled = !this.enabled
    }, c.prototype.toggle = function (b) {
        var c = this;
        b && (c = a(b.currentTarget).data("bs." + this.type), c || (c = new this.constructor(b.currentTarget, this.getDelegateOptions()), a(b.currentTarget).data("bs." + this.type, c))), b ? (c.inState.click = !c.inState.click, c.isInStateTrue() ? c.enter(c) : c.leave(c)) : c.tip().hasClass("in") ? c.leave(c) : c.enter(c)
    }, c.prototype.destroy = function () {
        var a = this;
        clearTimeout(this.timeout), this.hide(function () {
            a.$element.off("." + a.type).removeData("bs." + a.type), a.$tip && a.$tip.detach(), a.$tip = null, a.$arrow = null, a.$viewport = null, a.$element = null
        })
    };
    var d = a.fn.tooltip;
    a.fn.tooltip = b, a.fn.tooltip.Constructor = c, a.fn.tooltip.noConflict = function () {
        return a.fn.tooltip = d, this
    }
}(jQuery), + function (a) {
    "use strict";

    function b(b) {
        return this.each(function () {
            var d = a(this),
                e = d.data("bs.popover"),
                f = "object" == typeof b && b;
            !e && /destroy|hide/.test(b) || (e || d.data("bs.popover", e = new c(this, f)), "string" == typeof b && e[b]())
        })
    }
    var c = function (a, b) {
        this.init("popover", a, b)
    };
    if (!a.fn.tooltip) throw new Error("Popover requires tooltip.js");
    c.VERSION = "3.3.7", c.DEFAULTS = a.extend({}, a.fn.tooltip.Constructor.DEFAULTS, {
        placement: "right",
        trigger: "click",
        content: "",
        template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
    }), c.prototype = a.extend({}, a.fn.tooltip.Constructor.prototype), c.prototype.constructor = c, c.prototype.getDefaults = function () {
        return c.DEFAULTS
    }, c.prototype.setContent = function () {
        var a = this.tip(),
            b = this.getTitle(),
            c = this.getContent();
        a.find(".popover-title")[this.options.html ? "html" : "text"](b), a.find(".popover-content").children().detach().end()[this.options.html ? "string" == typeof c ? "html" : "append" : "text"](c), a.removeClass("fade top bottom left right in"), a.find(".popover-title").html() || a.find(".popover-title").hide()
    }, c.prototype.hasContent = function () {
        return this.getTitle() || this.getContent()
    }, c.prototype.getContent = function () {
        var a = this.$element,
            b = this.options;
        return a.attr("data-content") || ("function" == typeof b.content ? b.content.call(a[0]) : b.content)
    }, c.prototype.arrow = function () {
        return this.$arrow = this.$arrow || this.tip().find(".arrow")
    };
    var d = a.fn.popover;
    a.fn.popover = b, a.fn.popover.Constructor = c, a.fn.popover.noConflict = function () {
        return a.fn.popover = d, this
    }
}(jQuery), + function (a) {
    "use strict";

    function b(c, d) {
        this.$body = a(document.body), this.$scrollElement = a(a(c).is(document.body) ? window : c), this.options = a.extend({}, b.DEFAULTS, d), this.selector = (this.options.target || "") + " .nav li > a", this.offsets = [], this.targets = [], this.activeTarget = null, this.scrollHeight = 0, this.$scrollElement.on("scroll.bs.scrollspy", a.proxy(this.process, this)), this.refresh(), this.process()
    }

    function c(c) {
        return this.each(function () {
            var d = a(this),
                e = d.data("bs.scrollspy"),
                f = "object" == typeof c && c;
            e || d.data("bs.scrollspy", e = new b(this, f)), "string" == typeof c && e[c]()
        })
    }
    b.VERSION = "3.3.7", b.DEFAULTS = {
        offset: 10
    }, b.prototype.getScrollHeight = function () {
        return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)
    }, b.prototype.refresh = function () {
        var b = this,
            c = "offset",
            d = 0;
        this.offsets = [], this.targets = [], this.scrollHeight = this.getScrollHeight(), a.isWindow(this.$scrollElement[0]) || (c = "position", d = this.$scrollElement.scrollTop()), this.$body.find(this.selector).map(function () {
            var b = a(this),
                e = b.data("target") || b.attr("href"),
                f = /^#./.test(e) && a(e);
            return f && f.length && f.is(":visible") && [
                [f[c]().top + d, e]
            ] || null
        }).sort(function (a, b) {
            return a[0] - b[0]
        }).each(function () {
            b.offsets.push(this[0]), b.targets.push(this[1])
        })
    }, b.prototype.process = function () {
        var a, b = this.$scrollElement.scrollTop() + this.options.offset,
            c = this.getScrollHeight(),
            d = this.options.offset + c - this.$scrollElement.height(),
            e = this.offsets,
            f = this.targets,
            g = this.activeTarget;
        if (this.scrollHeight != c && this.refresh(), b >= d) return g != (a = f[f.length - 1]) && this.activate(a);
        if (g && b < e[0]) return this.activeTarget = null, this.clear();
        for (a = e.length; a--;) g != f[a] && b >= e[a] && (void 0 === e[a + 1] || b < e[a + 1]) && this.activate(f[a])
    }, b.prototype.activate = function (b) {
        this.activeTarget = b, this.clear();
        var c = this.selector + '[data-target="' + b + '"],' + this.selector + '[href="' + b + '"]',
            d = a(c).parents("li").addClass("active");
        d.parent(".dropdown-menu").length && (d = d.closest("li.dropdown").addClass("active")), d.trigger("activate.bs.scrollspy")
    }, b.prototype.clear = function () {
        a(this.selector).parentsUntil(this.options.target, ".active").removeClass("active")
    };
    var d = a.fn.scrollspy;
    a.fn.scrollspy = c, a.fn.scrollspy.Constructor = b, a.fn.scrollspy.noConflict = function () {
        return a.fn.scrollspy = d, this
    }, a(window).on("load.bs.scrollspy.data-api", function () {
        a('[data-spy="scroll"]').each(function () {
            var b = a(this);
            c.call(b, b.data())
        })
    })
}(jQuery), + function (a) {
    "use strict";

    function b(b) {
        return this.each(function () {
            var d = a(this),
                e = d.data("bs.tab");
            e || d.data("bs.tab", e = new c(this)), "string" == typeof b && e[b]()
        })
    }
    var c = function (b) {
        this.element = a(b)
    };
    c.VERSION = "3.3.7", c.TRANSITION_DURATION = 150, c.prototype.show = function () {
        var b = this.element,
            c = b.closest("ul:not(.dropdown-menu)"),
            d = b.data("target");
        if (d || (d = b.attr("href"), d = d && d.replace(/.*(?=#[^\s]*$)/, "")), !b.parent("li").hasClass("active")) {
            var e = c.find(".active:last a"),
                f = a.Event("hide.bs.tab", {
                    relatedTarget: b[0]
                }),
                g = a.Event("show.bs.tab", {
                    relatedTarget: e[0]
                });
            if (e.trigger(f), b.trigger(g), !g.isDefaultPrevented() && !f.isDefaultPrevented()) {
                var h = a(d);
                this.activate(b.closest("li"), c), this.activate(h, h.parent(), function () {
                    e.trigger({
                        type: "hidden.bs.tab",
                        relatedTarget: b[0]
                    }), b.trigger({
                        type: "shown.bs.tab",
                        relatedTarget: e[0]
                    })
                })
            }
        }
    }, c.prototype.activate = function (b, d, e) {
        function f() {
            g.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded", !1), b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded", !0), h ? (b[0].offsetWidth, b.addClass("in")) : b.removeClass("fade"), b.parent(".dropdown-menu").length && b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded", !0), e && e()
        }
        var g = d.find("> .active"),
            h = e && a.support.transition && (g.length && g.hasClass("fade") || !!d.find("> .fade").length);
        g.length && h ? g.one("bsTransitionEnd", f).emulateTransitionEnd(c.TRANSITION_DURATION) : f(), g.removeClass("in")
    };
    var d = a.fn.tab;
    a.fn.tab = b, a.fn.tab.Constructor = c, a.fn.tab.noConflict = function () {
        return a.fn.tab = d, this
    };
    var e = function (c) {
        c.preventDefault(), b.call(a(this), "show")
    };
    a(document).on("click.bs.tab.data-api", '[data-toggle="tab"]', e).on("click.bs.tab.data-api", '[data-toggle="pill"]', e)
}(jQuery), + function (a) {
    "use strict";

    function b(b) {
        return this.each(function () {
            var d = a(this),
                e = d.data("bs.affix"),
                f = "object" == typeof b && b;
            e || d.data("bs.affix", e = new c(this, f)), "string" == typeof b && e[b]()
        })
    }
    var c = function (b, d) {
        this.options = a.extend({}, c.DEFAULTS, d), this.$target = a(this.options.target).on("scroll.bs.affix.data-api", a.proxy(this.checkPosition, this)).on("click.bs.affix.data-api", a.proxy(this.checkPositionWithEventLoop, this)), this.$element = a(b), this.affixed = null, this.unpin = null, this.pinnedOffset = null, this.checkPosition()
    };
    c.VERSION = "3.3.7", c.RESET = "affix affix-top affix-bottom", c.DEFAULTS = {
        offset: 0,
        target: window
    }, c.prototype.getState = function (a, b, c, d) {
        var e = this.$target.scrollTop(),
            f = this.$element.offset(),
            g = this.$target.height();
        if (null != c && "top" == this.affixed) return e < c && "top";
        if ("bottom" == this.affixed) return null != c ? !(e + this.unpin <= f.top) && "bottom" : !(e + g <= a - d) && "bottom";
        var h = null == this.affixed,
            i = h ? e : f.top,
            j = h ? g : b;
        return null != c && e <= c ? "top" : null != d && i + j >= a - d && "bottom"
    }, c.prototype.getPinnedOffset = function () {
        if (this.pinnedOffset) return this.pinnedOffset;
        this.$element.removeClass(c.RESET).addClass("affix");
        var a = this.$target.scrollTop(),
            b = this.$element.offset();
        return this.pinnedOffset = b.top - a
    }, c.prototype.checkPositionWithEventLoop = function () {
        setTimeout(a.proxy(this.checkPosition, this), 1)
    }, c.prototype.checkPosition = function () {
        if (this.$element.is(":visible")) {
            var b = this.$element.height(),
                d = this.options.offset,
                e = d.top,
                f = d.bottom,
                g = Math.max(a(document).height(), a(document.body).height());
            "object" != typeof d && (f = e = d), "function" == typeof e && (e = d.top(this.$element)), "function" == typeof f && (f = d.bottom(this.$element));
            var h = this.getState(g, b, e, f);
            if (this.affixed != h) {
                null != this.unpin && this.$element.css("top", "");
                var i = "affix" + (h ? "-" + h : ""),
                    j = a.Event(i + ".bs.affix");
                if (this.$element.trigger(j), j.isDefaultPrevented()) return;
                this.affixed = h, this.unpin = "bottom" == h ? this.getPinnedOffset() : null, this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix", "affixed") + ".bs.affix")
            }
            "bottom" == h && this.$element.offset({
                top: g - b - f
            })
        }
    };
    var d = a.fn.affix;
    a.fn.affix = b, a.fn.affix.Constructor = c, a.fn.affix.noConflict = function () {
        return a.fn.affix = d, this
    }, a(window).on("load", function () {
        a('[data-spy="affix"]').each(function () {
            var c = a(this),
                d = c.data();
            d.offset = d.offset || {}, null != d.offsetBottom && (d.offset.bottom = d.offsetBottom), null != d.offsetTop && (d.offset.top = d.offsetTop), b.call(c, d)
        })
    })
}(jQuery);
define("bootstrap", ["jquery"], function () {});

/**
 * 
 * watermark-dom is an GPL FreeSoftware.
 * watermark-dom 是采用GPL的自由软件。
 * 注意：基于本项目源码从事科研、论文、系统开发，"最好"在文中或系统中表明来自于本项目的内容和创意，否则所有贡献者可能会鄙视你和你的项目。 使用本项目源码请尊重程序员职业和劳动
 * 
 * author:saucxs
 * contact:saucxs@163.com
 * License:GPL
 */


(function (watermark) {
    window.watermarkdivs = [];
    // 加载水印
    var loadMark = function (settings) {
        var defaultSettings = {
            watermark_txt: "测试水印",
            watermark_x: 20, //水印起始位置x轴坐标
            watermark_y: 20, //水印起始位置Y轴坐标
            watermark_rows: 0, //水印行数
            watermark_cols: 0, //水印列数
            watermark_x_space: 100, //水印x轴间隔
            watermark_y_space: 50, //水印y轴间隔
            watermark_font: '微软雅黑', //水印字体
            watermark_color: 'black', //水印字体颜色
            watermark_fontsize: '18px', //水印字体大小
            watermark_alpha: 0.15, //水印透明度，要求设置在大于等于0.003
            watermark_width: 150, //水印宽度
            watermark_height: 100, //水印长度
            watermark_angle: 15, //水印倾斜度数
        };
        //采用配置项替换默认值，作用类似jquery.extend
        if (arguments.length === 1 && typeof arguments[0] === "object") {
            var src = arguments[0] || {};
            for (key in src) {
                if (src[key] && defaultSettings[key] && src[key] === defaultSettings[key])
                    continue;
                else if (src[key])
                    defaultSettings[key] = src[key];
            }
        }

        if (window.watermarkdivs && window.watermarkdivs.length > 0) {
            document.body.removeChild(document.getElementById("otdivid"));
            window.watermarkdivs = [];
        }

        //获取页面最大宽度
        var page_width = Math.max(document.body.scrollWidth, document.body.clientWidth);
        //获取页面最大长度
        var page_height = Math.max(document.body.scrollHeight, document.body.clientHeight);

        // 创建文档碎片
        var oTemp = document.createDocumentFragment();
        //创建水印外壳div
        var otdiv = document.getElementById("otdivid");
        if (!otdiv) {
            otdiv = document.createElement('div');
            otdiv.id = "otdivid";
            otdiv.style.pointerEvents = "none";
            document.body.appendChild(otdiv);
        }

        //如果将水印列数设置为0，或水印列数设置过大，超过页面最大宽度，则重新计算水印列数和水印x轴间隔
        if (defaultSettings.watermark_cols == 0 || (parseInt(defaultSettings.watermark_x + defaultSettings.watermark_width * defaultSettings.watermark_cols + defaultSettings.watermark_x_space * (defaultSettings.watermark_cols - 1)) > page_width)) {
            defaultSettings.watermark_cols = parseInt((page_width - defaultSettings.watermark_x + defaultSettings.watermark_x_space) / (defaultSettings.watermark_width + defaultSettings.watermark_x_space));
            defaultSettings.watermark_x_space = parseInt((page_width - defaultSettings.watermark_x - defaultSettings.watermark_width * defaultSettings.watermark_cols) / (defaultSettings.watermark_cols - 1));
        }
        //如果将水印行数设置为0，或水印行数设置过大，超过页面最大长度，则重新计算水印行数和水印y轴间隔
        if (defaultSettings.watermark_rows == 0 || (parseInt(defaultSettings.watermark_y + defaultSettings.watermark_height * defaultSettings.watermark_rows + defaultSettings.watermark_y_space * (defaultSettings.watermark_rows - 1)) > page_height)) {
            defaultSettings.watermark_rows = parseInt((defaultSettings.watermark_y_space + page_height - defaultSettings.watermark_y) / (defaultSettings.watermark_height + defaultSettings.watermark_y_space));
            defaultSettings.watermark_y_space = parseInt(((page_height - defaultSettings.watermark_y) - defaultSettings.watermark_height * defaultSettings.watermark_rows) / (defaultSettings.watermark_rows - 1));
        }

        var x;
        var y;
        for (var i = 0; i < defaultSettings.watermark_rows; i++) {
            y = defaultSettings.watermark_y + (defaultSettings.watermark_y_space + defaultSettings.watermark_height) * i;
            for (var j = 0; j < defaultSettings.watermark_cols; j++) {
                x = defaultSettings.watermark_x + (defaultSettings.watermark_width + defaultSettings.watermark_x_space) * j;

                var mask_div = document.createElement('div');
                var oText = document.createTextNode(defaultSettings.watermark_txt);
                mask_div.appendChild(oText);
                // 设置水印相关属性start
                mask_div.id = 'mask_div' + i + j;
                //设置水印div倾斜显示
                mask_div.style.webkitTransform = "rotate(-" + defaultSettings.watermark_angle + "deg)";
                mask_div.style.MozTransform = "rotate(-" + defaultSettings.watermark_angle + "deg)";
                mask_div.style.msTransform = "rotate(-" + defaultSettings.watermark_angle + "deg)";
                mask_div.style.OTransform = "rotate(-" + defaultSettings.watermark_angle + "deg)";
                mask_div.style.transform = "rotate(-" + defaultSettings.watermark_angle + "deg)";
                mask_div.style.visibility = "";
                mask_div.style.position = "absolute";
                //选不中
                mask_div.style.left = x + 'px';
                mask_div.style.top = y + 'px';
                mask_div.style.overflow = "hidden";
                mask_div.style.zIndex = "9999";
                //mask_div.style.border="solid #eee 1px";
                mask_div.style.opacity = defaultSettings.watermark_alpha;
                mask_div.style.fontSize = defaultSettings.watermark_fontsize;
                mask_div.style.fontFamily = defaultSettings.watermark_font;
                mask_div.style.color = defaultSettings.watermark_color;
                mask_div.style.textAlign = "center";
                mask_div.style.width = defaultSettings.watermark_width + 'px';
                mask_div.style.height = defaultSettings.watermark_height + 'px';
                mask_div.style.display = "block";
                //设置水印相关属性end
                //附加到文档碎片中
                otdiv.appendChild(mask_div);

                window.watermarkdivs.push(otdiv); //控制页面大小变化时水印字体
            };
        };
        //一次性添加到document中
        document.body.appendChild(oTemp);
    };

    watermark.init = function (settings) {
        window.onload = function () {
            loadMark(settings);
        };
        window.onresize = function () {
            loadMark(settings);
        };
    };

    watermark.load = function (settings) {
        loadMark(settings);
    };

})(window.watermark = {});
define("watermark", function () {});

/*!
 * clipboard.js v2.0.4
 * https://zenorocha.github.io/clipboard.js
 * 
 * Licensed MIT © Zeno Rocha
 */
(function webpackUniversalModuleDefinition(root, factory) {
    if (typeof exports === 'object' && typeof module === 'object')
        module.exports = factory();
    else if (typeof define === 'function' && define.amd)
        define('clipboard', [], factory);
    else if (typeof exports === 'object')
        exports["ClipboardJS"] = factory();
    else
        root["ClipboardJS"] = factory();
})(this, function () {
    return /******/ (function (modules) { // webpackBootstrap
        /******/ // The module cache
        /******/
        var installedModules = {};
        /******/
        /******/ // The require function
        /******/
        function __webpack_require__(moduleId) {
            /******/
            /******/ // Check if module is in cache
            /******/
            if (installedModules[moduleId]) {
                /******/
                return installedModules[moduleId].exports;
                /******/
            }
            /******/ // Create a new module (and put it into the cache)
            /******/
            var module = installedModules[moduleId] = {
                /******/
                i: moduleId,
                /******/
                l: false,
                /******/
                exports: {}
                /******/
            };
            /******/
            /******/ // Execute the module function
            /******/
            modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
            /******/
            /******/ // Flag the module as loaded
            /******/
            module.l = true;
            /******/
            /******/ // Return the exports of the module
            /******/
            return module.exports;
            /******/
        }
        /******/
        /******/
        /******/ // expose the modules object (__webpack_modules__)
        /******/
        __webpack_require__.m = modules;
        /******/
        /******/ // expose the module cache
        /******/
        __webpack_require__.c = installedModules;
        /******/
        /******/ // define getter function for harmony exports
        /******/
        __webpack_require__.d = function (exports, name, getter) {
            /******/
            if (!__webpack_require__.o(exports, name)) {
                /******/
                Object.defineProperty(exports, name, {
                    enumerable: true,
                    get: getter
                });
                /******/
            }
            /******/
        };
        /******/
        /******/ // define __esModule on exports
        /******/
        __webpack_require__.r = function (exports) {
            /******/
            if (typeof Symbol !== 'undefined' && Symbol.toStringTag) {
                /******/
                Object.defineProperty(exports, Symbol.toStringTag, {
                    value: 'Module'
                });
                /******/
            }
            /******/
            Object.defineProperty(exports, '__esModule', {
                value: true
            });
            /******/
        };
        /******/
        /******/ // create a fake namespace object
        /******/ // mode & 1: value is a module id, require it
        /******/ // mode & 2: merge all properties of value into the ns
        /******/ // mode & 4: return value when already ns object
        /******/ // mode & 8|1: behave like require
        /******/
        __webpack_require__.t = function (value, mode) {
            /******/
            if (mode & 1) value = __webpack_require__(value);
            /******/
            if (mode & 8) return value;
            /******/
            if ((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
            /******/
            var ns = Object.create(null);
            /******/
            __webpack_require__.r(ns);
            /******/
            Object.defineProperty(ns, 'default', {
                enumerable: true,
                value: value
            });
            /******/
            if (mode & 2 && typeof value != 'string')
                for (var key in value) __webpack_require__.d(ns, key, function (key) {
                    return value[key];
                }.bind(null, key));
            /******/
            return ns;
            /******/
        };
        /******/
        /******/ // getDefaultExport function for compatibility with non-harmony modules
        /******/
        __webpack_require__.n = function (module) {
            /******/
            var getter = module && module.__esModule ?
                /******/
                function getDefault() {
                    return module['default'];
                } :
                /******/
                function getModuleExports() {
                    return module;
                };
            /******/
            __webpack_require__.d(getter, 'a', getter);
            /******/
            return getter;
            /******/
        };
        /******/
        /******/ // Object.prototype.hasOwnProperty.call
        /******/
        __webpack_require__.o = function (object, property) {
            return Object.prototype.hasOwnProperty.call(object, property);
        };
        /******/
        /******/ // __webpack_public_path__
        /******/
        __webpack_require__.p = "";
        /******/
        /******/
        /******/ // Load entry module and return exports
        /******/
        return __webpack_require__(__webpack_require__.s = 0);
        /******/
    })
    /************************************************************************/
    /******/
    ([
        /* 0 */
        /***/
        (function (module, exports, __webpack_require__) {




            var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
                return typeof obj;
            } : function (obj) {
                return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
            };

            var _createClass = function () {
                function defineProperties(target, props) {
                    for (var i = 0; i < props.length; i++) {
                        var descriptor = props[i];
                        descriptor.enumerable = descriptor.enumerable || false;
                        descriptor.configurable = true;
                        if ("value" in descriptor) descriptor.writable = true;
                        Object.defineProperty(target, descriptor.key, descriptor);
                    }
                }
                return function (Constructor, protoProps, staticProps) {
                    if (protoProps) defineProperties(Constructor.prototype, protoProps);
                    if (staticProps) defineProperties(Constructor, staticProps);
                    return Constructor;
                };
            }();

            var _clipboardAction = __webpack_require__(1);

            var _clipboardAction2 = _interopRequireDefault(_clipboardAction);

            var _tinyEmitter = __webpack_require__(3);

            var _tinyEmitter2 = _interopRequireDefault(_tinyEmitter);

            var _goodListener = __webpack_require__(4);

            var _goodListener2 = _interopRequireDefault(_goodListener);

            function _interopRequireDefault(obj) {
                return obj && obj.__esModule ? obj : {
                    default: obj
                };
            }

            function _classCallCheck(instance, Constructor) {
                if (!(instance instanceof Constructor)) {
                    throw new TypeError("Cannot call a class as a function");
                }
            }

            function _possibleConstructorReturn(self, call) {
                if (!self) {
                    throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
                }
                return call && (typeof call === "object" || typeof call === "function") ? call : self;
            }

            function _inherits(subClass, superClass) {
                if (typeof superClass !== "function" && superClass !== null) {
                    throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
                }
                subClass.prototype = Object.create(superClass && superClass.prototype, {
                    constructor: {
                        value: subClass,
                        enumerable: false,
                        writable: true,
                        configurable: true
                    }
                });
                if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
            }

            /**
             * Base class which takes one or more elements, adds event listeners to them,
             * and instantiates a new `ClipboardAction` on each click.
             */
            var Clipboard = function (_Emitter) {
                _inherits(Clipboard, _Emitter);

                /**
                 * @param {String|HTMLElement|HTMLCollection|NodeList} trigger
                 * @param {Object} options
                 */
                function Clipboard(trigger, options) {
                    _classCallCheck(this, Clipboard);

                    var _this = _possibleConstructorReturn(this, (Clipboard.__proto__ || Object.getPrototypeOf(Clipboard)).call(this));

                    _this.resolveOptions(options);
                    _this.listenClick(trigger);
                    return _this;
                }

                /**
                 * Defines if attributes would be resolved using internal setter functions
                 * or custom functions that were passed in the constructor.
                 * @param {Object} options
                 */


                _createClass(Clipboard, [{
                    key: 'resolveOptions',
                    value: function resolveOptions() {
                        var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

                        this.action = typeof options.action === 'function' ? options.action : this.defaultAction;
                        this.target = typeof options.target === 'function' ? options.target : this.defaultTarget;
                        this.text = typeof options.text === 'function' ? options.text : this.defaultText;
                        this.container = _typeof(options.container) === 'object' ? options.container : document.body;
                    }

                    /**
                     * Adds a click event listener to the passed trigger.
                     * @param {String|HTMLElement|HTMLCollection|NodeList} trigger
                     */

                }, {
                    key: 'listenClick',
                    value: function listenClick(trigger) {
                        var _this2 = this;

                        this.listener = (0, _goodListener2.default)(trigger, 'click', function (e) {
                            return _this2.onClick(e);
                        });
                    }

                    /**
                     * Defines a new `ClipboardAction` on each click event.
                     * @param {Event} e
                     */

                }, {
                    key: 'onClick',
                    value: function onClick(e) {
                        var trigger = e.delegateTarget || e.currentTarget;

                        if (this.clipboardAction) {
                            this.clipboardAction = null;
                        }

                        this.clipboardAction = new _clipboardAction2.default({
                            action: this.action(trigger),
                            target: this.target(trigger),
                            text: this.text(trigger),
                            container: this.container,
                            trigger: trigger,
                            emitter: this
                        });
                    }

                    /**
                     * Default `action` lookup function.
                     * @param {Element} trigger
                     */

                }, {
                    key: 'defaultAction',
                    value: function defaultAction(trigger) {
                        return getAttributeValue('action', trigger);
                    }

                    /**
                     * Default `target` lookup function.
                     * @param {Element} trigger
                     */

                }, {
                    key: 'defaultTarget',
                    value: function defaultTarget(trigger) {
                        var selector = getAttributeValue('target', trigger);

                        if (selector) {
                            return document.querySelector(selector);
                        }
                    }

                    /**
                     * Returns the support of the given action, or all actions if no action is
                     * given.
                     * @param {String} [action]
                     */

                }, {
                    key: 'defaultText',


                    /**
                     * Default `text` lookup function.
                     * @param {Element} trigger
                     */
                    value: function defaultText(trigger) {
                        return getAttributeValue('text', trigger);
                    }

                    /**
                     * Destroy lifecycle.
                     */

                }, {
                    key: 'destroy',
                    value: function destroy() {
                        this.listener.destroy();

                        if (this.clipboardAction) {
                            this.clipboardAction.destroy();
                            this.clipboardAction = null;
                        }
                    }
                }], [{
                    key: 'isSupported',
                    value: function isSupported() {
                        var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['copy', 'cut'];

                        var actions = typeof action === 'string' ? [action] : action;
                        var support = !!document.queryCommandSupported;

                        actions.forEach(function (action) {
                            support = support && !!document.queryCommandSupported(action);
                        });

                        return support;
                    }
                }]);

                return Clipboard;
            }(_tinyEmitter2.default);

            /**
             * Helper function to retrieve attribute value.
             * @param {String} suffix
             * @param {Element} element
             */


            function getAttributeValue(suffix, element) {
                var attribute = 'data-clipboard-' + suffix;

                if (!element.hasAttribute(attribute)) {
                    return;
                }

                return element.getAttribute(attribute);
            }

            module.exports = Clipboard;

            /***/
        }),
        /* 1 */
        /***/
        (function (module, exports, __webpack_require__) {




            var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
                return typeof obj;
            } : function (obj) {
                return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
            };

            var _createClass = function () {
                function defineProperties(target, props) {
                    for (var i = 0; i < props.length; i++) {
                        var descriptor = props[i];
                        descriptor.enumerable = descriptor.enumerable || false;
                        descriptor.configurable = true;
                        if ("value" in descriptor) descriptor.writable = true;
                        Object.defineProperty(target, descriptor.key, descriptor);
                    }
                }
                return function (Constructor, protoProps, staticProps) {
                    if (protoProps) defineProperties(Constructor.prototype, protoProps);
                    if (staticProps) defineProperties(Constructor, staticProps);
                    return Constructor;
                };
            }();

            var _select = __webpack_require__(2);

            var _select2 = _interopRequireDefault(_select);

            function _interopRequireDefault(obj) {
                return obj && obj.__esModule ? obj : {
                    default: obj
                };
            }

            function _classCallCheck(instance, Constructor) {
                if (!(instance instanceof Constructor)) {
                    throw new TypeError("Cannot call a class as a function");
                }
            }

            /**
             * Inner class which performs selection from either `text` or `target`
             * properties and then executes copy or cut operations.
             */
            var ClipboardAction = function () {
                /**
                 * @param {Object} options
                 */
                function ClipboardAction(options) {
                    _classCallCheck(this, ClipboardAction);

                    this.resolveOptions(options);
                    this.initSelection();
                }

                /**
                 * Defines base properties passed from constructor.
                 * @param {Object} options
                 */


                _createClass(ClipboardAction, [{
                    key: 'resolveOptions',
                    value: function resolveOptions() {
                        var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

                        this.action = options.action;
                        this.container = options.container;
                        this.emitter = options.emitter;
                        this.target = options.target;
                        this.text = options.text;
                        this.trigger = options.trigger;

                        this.selectedText = '';
                    }

                    /**
                     * Decides which selection strategy is going to be applied based
                     * on the existence of `text` and `target` properties.
                     */

                }, {
                    key: 'initSelection',
                    value: function initSelection() {
                        if (this.text) {
                            this.selectFake();
                        } else if (this.target) {
                            this.selectTarget();
                        }
                    }

                    /**
                     * Creates a fake textarea element, sets its value from `text` property,
                     * and makes a selection on it.
                     */

                }, {
                    key: 'selectFake',
                    value: function selectFake() {
                        var _this = this;

                        var isRTL = document.documentElement.getAttribute('dir') == 'rtl';

                        this.removeFake();

                        this.fakeHandlerCallback = function () {
                            return _this.removeFake();
                        };
                        this.fakeHandler = this.container.addEventListener('click', this.fakeHandlerCallback) || true;

                        this.fakeElem = document.createElement('textarea');
                        // Prevent zooming on iOS
                        this.fakeElem.style.fontSize = '12pt';
                        // Reset box model
                        this.fakeElem.style.border = '0';
                        this.fakeElem.style.padding = '0';
                        this.fakeElem.style.margin = '0';
                        // Move element out of screen horizontally
                        this.fakeElem.style.position = 'absolute';
                        this.fakeElem.style[isRTL ? 'right' : 'left'] = '-9999px';
                        // Move element to the same position vertically
                        var yPosition = window.pageYOffset || document.documentElement.scrollTop;
                        this.fakeElem.style.top = yPosition + 'px';

                        this.fakeElem.setAttribute('readonly', '');
                        this.fakeElem.value = this.text;

                        this.container.appendChild(this.fakeElem);

                        this.selectedText = (0, _select2.default)(this.fakeElem);
                        this.copyText();
                    }

                    /**
                     * Only removes the fake element after another click event, that way
                     * a user can hit `Ctrl+C` to copy because selection still exists.
                     */

                }, {
                    key: 'removeFake',
                    value: function removeFake() {
                        if (this.fakeHandler) {
                            this.container.removeEventListener('click', this.fakeHandlerCallback);
                            this.fakeHandler = null;
                            this.fakeHandlerCallback = null;
                        }

                        if (this.fakeElem) {
                            this.container.removeChild(this.fakeElem);
                            this.fakeElem = null;
                        }
                    }

                    /**
                     * Selects the content from element passed on `target` property.
                     */

                }, {
                    key: 'selectTarget',
                    value: function selectTarget() {
                        this.selectedText = (0, _select2.default)(this.target);
                        this.copyText();
                    }

                    /**
                     * Executes the copy operation based on the current selection.
                     */

                }, {
                    key: 'copyText',
                    value: function copyText() {
                        var succeeded = void 0;

                        try {
                            succeeded = document.execCommand(this.action);
                        } catch (err) {
                            succeeded = false;
                        }

                        this.handleResult(succeeded);
                    }

                    /**
                     * Fires an event based on the copy operation result.
                     * @param {Boolean} succeeded
                     */

                }, {
                    key: 'handleResult',
                    value: function handleResult(succeeded) {
                        this.emitter.emit(succeeded ? 'success' : 'error', {
                            action: this.action,
                            text: this.selectedText,
                            trigger: this.trigger,
                            clearSelection: this.clearSelection.bind(this)
                        });
                    }

                    /**
                     * Moves focus away from `target` and back to the trigger, removes current selection.
                     */

                }, {
                    key: 'clearSelection',
                    value: function clearSelection() {
                        if (this.trigger) {
                            this.trigger.focus();
                        }

                        window.getSelection().removeAllRanges();
                    }

                    /**
                     * Sets the `action` to be performed which can be either 'copy' or 'cut'.
                     * @param {String} action
                     */

                }, {
                    key: 'destroy',


                    /**
                     * Destroy lifecycle.
                     */
                    value: function destroy() {
                        this.removeFake();
                    }
                }, {
                    key: 'action',
                    set: function set() {
                            var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'copy';

                            this._action = action;

                            if (this._action !== 'copy' && this._action !== 'cut') {
                                throw new Error('Invalid "action" value, use either "copy" or "cut"');
                            }
                        }

                        /**
                         * Gets the `action` property.
                         * @return {String}
                         */
                        ,
                    get: function get() {
                        return this._action;
                    }

                    /**
                     * Sets the `target` property using an element
                     * that will be have its content copied.
                     * @param {Element} target
                     */

                }, {
                    key: 'target',
                    set: function set(target) {
                            if (target !== undefined) {
                                if (target && (typeof target === 'undefined' ? 'undefined' : _typeof(target)) === 'object' && target.nodeType === 1) {
                                    if (this.action === 'copy' && target.hasAttribute('disabled')) {
                                        throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');
                                    }

                                    if (this.action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) {
                                        throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes');
                                    }

                                    this._target = target;
                                } else {
                                    throw new Error('Invalid "target" value, use a valid Element');
                                }
                            }
                        }

                        /**
                         * Gets the `target` property.
                         * @return {String|HTMLElement}
                         */
                        ,
                    get: function get() {
                        return this._target;
                    }
                }]);

                return ClipboardAction;
            }();

            module.exports = ClipboardAction;

            /***/
        }),
        /* 2 */
        /***/
        (function (module, exports) {

            function select(element) {
                var selectedText;

                if (element.nodeName === 'SELECT') {
                    element.focus();

                    selectedText = element.value;
                } else if (element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA') {
                    var isReadOnly = element.hasAttribute('readonly');

                    if (!isReadOnly) {
                        element.setAttribute('readonly', '');
                    }

                    element.select();
                    element.setSelectionRange(0, element.value.length);

                    if (!isReadOnly) {
                        element.removeAttribute('readonly');
                    }

                    selectedText = element.value;
                } else {
                    if (element.hasAttribute('contenteditable')) {
                        element.focus();
                    }

                    var selection = window.getSelection();
                    var range = document.createRange();

                    range.selectNodeContents(element);
                    selection.removeAllRanges();
                    selection.addRange(range);

                    selectedText = selection.toString();
                }

                return selectedText;
            }

            module.exports = select;


            /***/
        }),
        /* 3 */
        /***/
        (function (module, exports) {

            function E() {
                // Keep this empty so it's easier to inherit from
                // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)
            }

            E.prototype = {
                on: function (name, callback, ctx) {
                    var e = this.e || (this.e = {});

                    (e[name] || (e[name] = [])).push({
                        fn: callback,
                        ctx: ctx
                    });

                    return this;
                },

                once: function (name, callback, ctx) {
                    var self = this;

                    function listener() {
                        self.off(name, listener);
                        callback.apply(ctx, arguments);
                    };

                    listener._ = callback
                    return this.on(name, listener, ctx);
                },

                emit: function (name) {
                    var data = [].slice.call(arguments, 1);
                    var evtArr = ((this.e || (this.e = {}))[name] || []).slice();
                    var i = 0;
                    var len = evtArr.length;

                    for (i; i < len; i++) {
                        evtArr[i].fn.apply(evtArr[i].ctx, data);
                    }

                    return this;
                },

                off: function (name, callback) {
                    var e = this.e || (this.e = {});
                    var evts = e[name];
                    var liveEvents = [];

                    if (evts && callback) {
                        for (var i = 0, len = evts.length; i < len; i++) {
                            if (evts[i].fn !== callback && evts[i].fn._ !== callback)
                                liveEvents.push(evts[i]);
                        }
                    }

                    // Remove event from queue to prevent memory leak
                    // Suggested by https://github.com/lazd
                    // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910

                    (liveEvents.length) ?
                    e[name] = liveEvents: delete e[name];

                    return this;
                }
            };

            module.exports = E;


            /***/
        }),
        /* 4 */
        /***/
        (function (module, exports, __webpack_require__) {

            var is = __webpack_require__(5);
            var delegate = __webpack_require__(6);

            /**
             * Validates all params and calls the right
             * listener function based on its target type.
             *
             * @param {String|HTMLElement|HTMLCollection|NodeList} target
             * @param {String} type
             * @param {Function} callback
             * @return {Object}
             */
            function listen(target, type, callback) {
                if (!target && !type && !callback) {
                    throw new Error('Missing required arguments');
                }

                if (!is.string(type)) {
                    throw new TypeError('Second argument must be a String');
                }

                if (!is.fn(callback)) {
                    throw new TypeError('Third argument must be a Function');
                }

                if (is.node(target)) {
                    return listenNode(target, type, callback);
                } else if (is.nodeList(target)) {
                    return listenNodeList(target, type, callback);
                } else if (is.string(target)) {
                    return listenSelector(target, type, callback);
                } else {
                    throw new TypeError('First argument must be a String, HTMLElement, HTMLCollection, or NodeList');
                }
            }

            /**
             * Adds an event listener to a HTML element
             * and returns a remove listener function.
             *
             * @param {HTMLElement} node
             * @param {String} type
             * @param {Function} callback
             * @return {Object}
             */
            function listenNode(node, type, callback) {
                node.addEventListener(type, callback);

                return {
                    destroy: function () {
                        node.removeEventListener(type, callback);
                    }
                }
            }

            /**
             * Add an event listener to a list of HTML elements
             * and returns a remove listener function.
             *
             * @param {NodeList|HTMLCollection} nodeList
             * @param {String} type
             * @param {Function} callback
             * @return {Object}
             */
            function listenNodeList(nodeList, type, callback) {
                Array.prototype.forEach.call(nodeList, function (node) {
                    node.addEventListener(type, callback);
                });

                return {
                    destroy: function () {
                        Array.prototype.forEach.call(nodeList, function (node) {
                            node.removeEventListener(type, callback);
                        });
                    }
                }
            }

            /**
             * Add an event listener to a selector
             * and returns a remove listener function.
             *
             * @param {String} selector
             * @param {String} type
             * @param {Function} callback
             * @return {Object}
             */
            function listenSelector(selector, type, callback) {
                return delegate(document.body, selector, type, callback);
            }

            module.exports = listen;


            /***/
        }),
        /* 5 */
        /***/
        (function (module, exports) {

            /**
             * Check if argument is a HTML element.
             *
             * @param {Object} value
             * @return {Boolean}
             */
            exports.node = function (value) {
                return value !== undefined &&
                    value instanceof HTMLElement &&
                    value.nodeType === 1;
            };

            /**
             * Check if argument is a list of HTML elements.
             *
             * @param {Object} value
             * @return {Boolean}
             */
            exports.nodeList = function (value) {
                var type = Object.prototype.toString.call(value);

                return value !== undefined &&
                    (type === '[object NodeList]' || type === '[object HTMLCollection]') &&
                    ('length' in value) &&
                    (value.length === 0 || exports.node(value[0]));
            };

            /**
             * Check if argument is a string.
             *
             * @param {Object} value
             * @return {Boolean}
             */
            exports.string = function (value) {
                return typeof value === 'string' ||
                    value instanceof String;
            };

            /**
             * Check if argument is a function.
             *
             * @param {Object} value
             * @return {Boolean}
             */
            exports.fn = function (value) {
                var type = Object.prototype.toString.call(value);

                return type === '[object Function]';
            };


            /***/
        }),
        /* 6 */
        /***/
        (function (module, exports, __webpack_require__) {

            var closest = __webpack_require__(7);

            /**
             * Delegates event to a selector.
             *
             * @param {Element} element
             * @param {String} selector
             * @param {String} type
             * @param {Function} callback
             * @param {Boolean} useCapture
             * @return {Object}
             */
            function _delegate(element, selector, type, callback, useCapture) {
                var listenerFn = listener.apply(this, arguments);

                element.addEventListener(type, listenerFn, useCapture);

                return {
                    destroy: function () {
                        element.removeEventListener(type, listenerFn, useCapture);
                    }
                }
            }

            /**
             * Delegates event to a selector.
             *
             * @param {Element|String|Array} [elements]
             * @param {String} selector
             * @param {String} type
             * @param {Function} callback
             * @param {Boolean} useCapture
             * @return {Object}
             */
            function delegate(elements, selector, type, callback, useCapture) {
                // Handle the regular Element usage
                if (typeof elements.addEventListener === 'function') {
                    return _delegate.apply(null, arguments);
                }

                // Handle Element-less usage, it defaults to global delegation
                if (typeof type === 'function') {
                    // Use `document` as the first parameter, then apply arguments
                    // This is a short way to .unshift `arguments` without running into deoptimizations
                    return _delegate.bind(null, document).apply(null, arguments);
                }

                // Handle Selector-based usage
                if (typeof elements === 'string') {
                    elements = document.querySelectorAll(elements);
                }

                // Handle Array-like based usage
                return Array.prototype.map.call(elements, function (element) {
                    return _delegate(element, selector, type, callback, useCapture);
                });
            }

            /**
             * Finds closest match and invokes callback.
             *
             * @param {Element} element
             * @param {String} selector
             * @param {String} type
             * @param {Function} callback
             * @return {Function}
             */
            function listener(element, selector, type, callback) {
                return function (e) {
                    e.delegateTarget = closest(e.target, selector);

                    if (e.delegateTarget) {
                        callback.call(element, e);
                    }
                }
            }

            module.exports = delegate;


            /***/
        }),
        /* 7 */
        /***/
        (function (module, exports) {

            var DOCUMENT_NODE_TYPE = 9;

            /**
             * A polyfill for Element.matches()
             */
            if (typeof Element !== 'undefined' && !Element.prototype.matches) {
                var proto = Element.prototype;

                proto.matches = proto.matchesSelector ||
                    proto.mozMatchesSelector ||
                    proto.msMatchesSelector ||
                    proto.oMatchesSelector ||
                    proto.webkitMatchesSelector;
            }

            /**
             * Finds the closest parent that matches a selector.
             *
             * @param {Element} element
             * @param {String} selector
             * @return {Function}
             */
            function closest(element, selector) {
                while (element && element.nodeType !== DOCUMENT_NODE_TYPE) {
                    if (typeof element.matches === 'function' &&
                        element.matches(selector)) {
                        return element;
                    }
                    element = element.parentNode;
                }
            }

            module.exports = closest;


            /***/
        })
        /******/
    ]);
});
require.config({
    urlArgs: "v=" + requirejs.s.contexts._.config.config.site.version,
    packages: [{
        name: 'moment',
        location: '../libs/moment',
        main: 'moment'
    }],
    //在打包压缩时将会把include中的模块合并到主文件中
    include: ['css', 'layer', 'toastr', 'fast', 'backend', 'backend-init', 'table', 'form', 'dragsort', 'drag', 'drop', 'addtabs', 'selectpage', 'editable-select'],
    paths: {
        'lang': "empty:",
        'form': 'require-form',
        'table': 'require-table',
        'addons': 'addons',
        'spark': 'spark',
        'upload': 'require-upload',
        'validator': 'require-validator',
        'drag': 'jquery.drag.min',
        'drop': 'jquery.drop.min',
        'echarts': 'echarts.min',
        'echarts-theme': 'echarts-theme',
        'adminlte': 'adminlte',
        'bootstrap-table-commonsearch': 'bootstrap-table-commonsearch',
        'bootstrap-table-template': 'bootstrap-table-template',
        //
        // 以下的包从bower的libs目录加载
        'jquery': '../libs/jquery/dist/jquery.min',
        'bootstrap': '../libs/bootstrap/dist/js/bootstrap.min',
        'bootstrap-datetimepicker': '../libs/eonasdan-bootstrap-datetimepicker/build/js/bootstrap-datetimepicker.min',
        'bootstrap-daterangepicker': '../libs/bootstrap-daterangepicker/daterangepicker',
        'bootstrap-select': '../libs/bootstrap-select/dist/js/bootstrap-select.min',
        'bootstrap-select-lang': '../libs/bootstrap-select/dist/js/i18n/defaults-zh_CN',
        'bootstrap-table': '../libs/bootstrap-table/dist/bootstrap-table.min',
        'bootstrap-table-maintain': '../libs/bootstrap-table-maintainColSwitch/bootstrap-table-maintainColSwitch.min',
        'bootstrap-table-export': '../libs/bootstrap-table/dist/extensions/export/bootstrap-table-export.min',
        'bootstrap-table-mobile': '../libs/bootstrap-table/dist/extensions/mobile/bootstrap-table-mobile',
        'bootstrap-table-lang': '../libs/bootstrap-table/dist/locale/bootstrap-table-zh-CN',
        'tagsinput': '../libs/bootstrap-tagsinput/bootstrap-tagsinput.min',
        'typeahead': '../libs/typeahead/typeahead.min',
        'bloodhound': '../libs/typeahead/bloodhound.min',
        'tableexport': '../libs/tableExport.jquery.plugin/tableExport.min',
        'bootstrap-table-editable': '../libs/bootstrap-table/dist/extensions/editable/bootstrap-table-editable.min',
        'bootstrap-editable': '../libs/bootstrap-table/dist/extensions/editable/bootstrap-editable',
        'dragsort': '../libs/fastadmin-dragsort/jquery.dragsort',
        'sortable': '../libs/Sortable/Sortable.min',
        'addtabs': '../libs/fastadmin-addtabs/jquery.addtabs',
        'slimscroll': '../libs/jquery-slimscroll/jquery.slimscroll',
        'validator-core': '../libs/nice-validator/dist/jquery.validator',
        'validator-lang': '../libs/nice-validator/dist/local/zh-CN',

        'toastr': '../libs/toastr/toastr',
        'jstree': '../libs/jstree/dist/jstree.min',
        'layer': '../libs/layer/dist/layer',
        'cookie': '../libs/jquery.cookie/jquery.cookie',
        'cxselect': '../libs/fastadmin-cxselect/js/jquery.cxselect',
        'template': '../libs/art-template/dist/template-native',
        'selectpage': '../libs/fastadmin-selectpage/selectpage',
        'citypicker': '../libs/fastadmin-citypicker/dist/js/city-picker.min',
        'citypicker-data': '../libs/fastadmin-citypicker/dist/js/city-picker.data',
        'QRCode': '../libs/qrcode/qrcode.min',
        'editable-select': '../libs/jquery-editable-select/jquery-editable-select',
        'bootstrap-table-pagejump': '../libs/bootstrap-table/src/extensions/page-jump/bootstrap-table-pagejump',
        'countdown': 'https://h5.dhcc.wang/api/jquery.countdown',
        'context-menu': '../libs/jquery-context-menu/js/jquery.contextMenu.min',
        'jquery-ui': 'jquery-ui.min',
        'pagination': 'jquery.pagination',
        'vue-lazyload': 'vue-lazyload',
        'moment': '../libs/moment'
    },
    // shim依赖配置
    shim: {
        'addons': ['backend'],
        'bootstrap': ['jquery'],
        'bootstrap-table': {
            deps: [
                'bootstrap',
                //                'css!../libs/bootstrap-table/dist/bootstrap-table.min.css'
            ],
            exports: '$.fn.bootstrapTable'
        },
        'bootstrap-table-lang': {
            deps: ['bootstrap-table'],
            exports: '$.fn.bootstrapTable.defaults'
        },
        'bootstrap-table-export': {
            deps: ['bootstrap-table', 'tableexport'],
            exports: '$.fn.bootstrapTable.defaults'
        },
        'bootstrap-table-mobile': {
            deps: ['bootstrap-table'],
            exports: '$.fn.bootstrapTable.defaults'
        },
        'bootstrap-table-advancedsearch': {
            deps: ['bootstrap-table'],
            exports: '$.fn.bootstrapTable.defaults'
        },
        'bootstrap-table-commonsearch': {
            deps: ['bootstrap-table'],
            exports: '$.fn.bootstrapTable.defaults'
        },
        'bootstrap-table-template': {
            deps: ['bootstrap-table', 'template'],
            exports: '$.fn.bootstrapTable.defaults'
        },
        'bootstrap-table-editable': {
            deps: ['bootstrap-table', 'bootstrap-editable'],
            exports: '$.fn.bootstrapTable.defaults'
        },
        'bootstrap-table-maintain': {
            deps: ['bootstrap-table', 'cookie'],
            exports: '$.fn.bootstrapTable.defaults'
        },
        'tagsinput': [
            'css!../libs/bootstrap-tagsinput/bootstrap-tagsinput.css',
            'css!../libs/bootstrap-tagsinput/bootstrap-tagsinput-typeahead.css',
        ],
        'typeahead': ['bloodhound'],
        'tableexport': {
            deps: ['jquery'],
            exports: '$.fn.extend'
        },
        'slimscroll': {
            deps: ['jquery'],
            exports: '$.fn.extend'
        },
        'adminlte': {
            deps: ['bootstrap', 'slimscroll'],
            exports: '$.AdminLTE'
        },
        'bootstrap-datetimepicker': [
            'moment/locale/zh-cn',
            //            'css!../libs/eonasdan-bootstrap-datetimepicker/build/css/bootstrap-datetimepicker.min.css',
        ],
        //        'bootstrap-select': ['css!../libs/bootstrap-select/dist/css/bootstrap-select.min.css',],
        'bootstrap-select-lang': ['bootstrap-select'],
        //        'toastr': ['css!../libs/toastr/toastr.min.css'],
        'jstree': ['css!../libs/jstree/dist/themes/default/style.css', ],

        //        'layer': ['css!../libs/layer/dist/theme/default/layer.css'],
        //        'validator-core': ['css!../libs/nice-validator/dist/jquery.validator.css'],
        'validator-lang': ['validator-core'],
        //        'selectpage': ['css!../libs/fastadmin-selectpage/selectpage.css'],
        'citypicker': ['citypicker-data', 'css!../libs/fastadmin-citypicker/dist/css/city-picker.css'],
        QRCode: {
            deps: [],
            exports: 'QRCode'
        },
        'bootstrap-table-pagejump': {
            deps: ['bootstrap-table'],
            exports: '$.fn.bootstrapTable.defaults',
        },
        'context-menu': ['jquery'],
    },
    baseUrl: requirejs.s.contexts._.config.config.site.cdnurl + '/assets/js/', //资源基础路径
    map: {
        '*': {
            'css': '../libs/require-css/css.min'
        }
    },
    waitSeconds: 30,
    charset: 'utf-8' // 文件编码
});


require.config({
    urlArgs: "v=" + requirejs.s.contexts._.config.config.site.version,
    packages: [{
        name: 'moment',
        location: '../libs/moment',
        main: 'moment'
    }],
    //在打包压缩时将会把include中的模块合并到主文件中
    include: ['css', 'layer', 'toastr', 'fast', 'backend', 'backend-init', 'table', 'form', 'dragsort', 'addtabs', 'selectpage', 'bootstrap-daterangepicker'],
    paths: {
        'lang': "empty:",
        'form': 'require-form',
        'table': 'require-table',
        'upload': 'require-upload',
        'dropzone': 'dropzone.min',
        'echarts': 'echarts.min',
        'echarts-theme': 'echarts-theme',
        'adminlte': 'adminlte',
        'bootstrap-table-commonsearch': 'bootstrap-table-commonsearch',
        'bootstrap-table-template': 'bootstrap-table-template',
        //
        // 以下的包从bower的libs目录加载
        'jquery': '../libs/jquery/dist/jquery.min',
        'bootstrap': '../libs/bootstrap/dist/js/bootstrap.min',
        'bootstrap-datetimepicker': '../libs/eonasdan-bootstrap-datetimepicker/build/js/bootstrap-datetimepicker.min',
        'bootstrap-daterangepicker': '../libs/bootstrap-daterangepicker/daterangepicker',
        'bootstrap-select': '../libs/bootstrap-select/dist/js/bootstrap-select.min',
        'bootstrap-select-lang': '../libs/bootstrap-select/dist/js/i18n/defaults-zh_CN',
        'bootstrap-table': '../libs/bootstrap-table/dist/bootstrap-table.min',
        'bootstrap-table-export': '../libs/bootstrap-table/dist/extensions/export/bootstrap-table-export.min',
        'bootstrap-table-fixed-columns': '../libs/bootstrap-table/dist/extensions/fixed-columns/bootstrap-table-fixed-columns',
        'bootstrap-table-mobile': '../libs/bootstrap-table/dist/extensions/mobile/bootstrap-table-mobile',
        'bootstrap-table-lang': '../libs/bootstrap-table/dist/locale/bootstrap-table-zh-CN',
        'bootstrap-table-jumpto': '../libs/bootstrap-table/dist/extensions/page-jumpto/bootstrap-table-jumpto',
        'bootstrap-slider': '../libs/bootstrap-slider/bootstrap-slider',
        'tableexport': '../libs/tableExport.jquery.plugin/tableExport.min',
        'dragsort': '../libs/fastadmin-dragsort/jquery.dragsort',
        'sortable': '../libs/Sortable/Sortable.min',
        'addtabs': '../libs/fastadmin-addtabs/jquery.addtabs',
        'slimscroll': '../libs/jquery-slimscroll/jquery.slimscroll',
        'validator': '../libs/nice-validator/dist/jquery.validator',
        'validator-lang': '../libs/nice-validator/dist/local/zh-CN',
        'toastr': '../libs/toastr/toastr',
        'jstree': '../libs/jstree/dist/jstree.min',
        'layer': '../libs/fastadmin-layer/dist/layer',
        'cookie': '../libs/jquery.cookie/jquery.cookie',
        'cxselect': '../libs/fastadmin-cxselect/js/jquery.cxselect',
        'template': '../libs/art-template/dist/template-native',
        'selectpage': '../libs/fastadmin-selectpage/selectpage',
        'citypicker': '../libs/fastadmin-citypicker/dist/js/city-picker.min',
        'citypicker-data': '../libs/fastadmin-citypicker/dist/js/city-picker.data',
    },
    // shim依赖配置
    shim: {
        'addons': ['backend'],
        'bootstrap': ['jquery'],
        'bootstrap-table': {
            deps: ['bootstrap'],
            exports: '$.fn.bootstrapTable'
        },
        'bootstrap-table-lang': {
            deps: ['bootstrap-table'],
            exports: '$.fn.bootstrapTable.defaults'
        },
        'bootstrap-table-export': {
            deps: ['bootstrap-table'],
            exports: '$.fn.bootstrapTable.defaults'
        },
        'bootstrap-table-fixed-columns': {
            deps: ['bootstrap-table'],
            exports: '$.fn.bootstrapTable.defaults'
        },
        'bootstrap-table-mobile': {
            deps: ['bootstrap-table'],
            exports: '$.fn.bootstrapTable.defaults'
        },
        'bootstrap-table-advancedsearch': {
            deps: ['bootstrap-table'],
            exports: '$.fn.bootstrapTable.defaults'
        },
        'bootstrap-table-commonsearch': {
            deps: ['bootstrap-table'],
            exports: '$.fn.bootstrapTable.defaults'
        },
        'bootstrap-table-template': {
            deps: ['bootstrap-table', 'template'],
            exports: '$.fn.bootstrapTable.defaults'
        },
        'bootstrap-table-jumpto': {
            deps: ['bootstrap-table'],
            exports: '$.fn.bootstrapTable.defaults'
        },
        'tableexport': {
            deps: ['jquery'],
            exports: '$.fn.extend'
        },
        'slimscroll': {
            deps: ['jquery'],
            exports: '$.fn.extend'
        },
        'adminlte': {
            deps: ['bootstrap', 'slimscroll'],
            exports: '$.AdminLTE'
        },
        'bootstrap-daterangepicker': [
            'moment/locale/zh-cn'
        ],
        'bootstrap-datetimepicker': [
            'moment/locale/zh-cn',
        ],
        'bootstrap-select-lang': ['bootstrap-select'],
        'jstree': ['css!../libs/jstree/dist/themes/default/style.css'],
        'validator-lang': ['validator'],
        'citypicker': ['citypicker-data', 'css!../libs/fastadmin-citypicker/dist/css/city-picker.css']
    },
    baseUrl: requirejs.s.contexts._.config.config.site.cdnurl + '/assets/js/', //资源基础路径
    map: {
        '*': {
            'css': '../libs/require-css/css.min'
        }
    },
    waitSeconds: 60,
    charset: 'utf-8' // 文件编码
});
require(['jquery', 'bootstrap', 'watermark', 'clipboard'], function ($, undefined, undefined, ClipboardJS) {
    //初始配置
    var Config = requirejs.s.contexts._.config.config;
    //将Config渲染到全局
    window.Config = Config;
    // 配置语言包的路径
    var paths = {};
    paths['lang'] = Config.moduleurl + '/ajax/lang?callback=define&controllername=' + Config.controllername;
    // 避免目录冲突
    paths['backend/'] = 'backend/';
    require.config({
        paths: paths
    });
    var clipboard = new ClipboardJS('.copy');
    clipboard.on('success', function (e) {
        Toastr.success("复制成功");
    });


    //自定义button给导出用
    $(".btn-big-export").click(function () {
        var template_sign = $(this).data("down");
        var url = "export/exportdownrecord/index/" + template_sign;
        var title = $(this).html();
        Fast.api.open(url, title, {
            callback: function (value) {}
        });
        return false;
    })

    // 初始化
    $(function () {

        //外链和视频教程开关
        var admin_path = Config.moduleurl;
        var modulename = Config.modulename;
        if (modulename == 'admin' && Config.actionname != 'login') {
            $.getJSON(admin_path + '/user/user/getlinkstatus', function (data) {
                if (data.code) {
                    if (data.data.link_status == 1) {
                        $('.btn-dialog-video').removeClass('hidden').show();
                        $('.btn-link-status').removeClass('hidden').show();
                    } else {
                        $('.btn-dialog-video').hide();
                        $('.btn-link-status').hide();
                    }
                }
            })
        }

        //导出按钮开关
        var export_btn = $('.btn-big-export').data("down");
        if (export_btn != undefined) {
            $.getJSON(admin_path + '/export/exportdownrecord/checkExportBtn', {
                'template_sign': export_btn
            }, function (data) {
                if (data.status == 1) {
                    $("button[data-down='" + export_btn + "']").removeClass('hide');
                }
            })
        }

        $(document).on('click', '.btn-dialog-video', function (e) {
            var that = this;
            var url = $(that).attr('data-href');
            var title = $(that).data('video-title');
            title = title ? title : $(that).html();
            Layer.open({
                type: 2,
                title: title,
                shadeClose: true,
                shade: false,
                maxmin: true,
                moveOut: true,
                area: ['90%', '90%'],
                content: url,
                zIndex: Layer.zIndex
            });
            return false;
        });
        $(document).on('click', '.btn-dialog-mobile', function (e) {
            var that = this;
            var url = $(that).attr('data-href');
            var title = $(that).attr('data-title');
            title = title ? title : $(that).html();
            Layer.open({
                type: 2,
                title: title,
                shadeClose: true,
                shade: false,
                maxmin: true,
                moveOut: true,
                area: ['20%', '80%'],
                content: url,
                zIndex: Layer.zIndex
            });
            return false;
        });
        $(document).on('click', '.btn-dialog-large', function (e) {
            var that = this;
            var url = $(that).attr('data-href');
            var title = $(that).attr('data-title');
            title = title ? title : $(that).html();
            Layer.open({
                type: 2,
                title: title,
                shadeClose: true,
                shade: false,
                maxmin: true,
                moveOut: true,
                area: ['90%', '90%'],
                content: url,
                zIndex: Layer.zIndex
            });
            return false;
        });
        $(".btn-group .btn").click(function () {
            $(this).addClass('active').siblings().removeClass('active')
        });
        $(document).on('click', '.btn-dialog-emoji', function (e) {
            var that = this;
            var url = $(that).attr('data-href');
            var title = $(that).data('data-title');
            title = title ? title : $(that).html();
            Layer.open({
                type: 2,
                title: title,
                shadeClose: true,
                shade: false,
                maxmin: true,
                moveOut: true,
                area: ['70%', '70%'],
                content: url,
                zIndex: Layer.zIndex
            });
            return false;
        });
        //选择会员
        $(document).on('click', '.btn-dialog-user', function (e) {
            var that = this;
            parent.Fast.api.open("user/user/select", __('选择会员'), {
                callback: function (data) {
                    var mobile = data.row.mobile ? " （" + data.row.mobile + "）" : '';
                    var show = data.row.nickname + " " + mobile + "";
                    $(that).parent().find('.selectpage-show').html(show);
                    $(that).parent().find('.selectpage-user_id').val(data.user_id);
                    $('#btn-save').removeClass("hide").show();
                }
            });
            return false;
        });

        function checkapp() {
            $.getJSON(Config.moduleurl + '/ajax/checkapp', {
                app_id: Config.app_id
            }, function (data) {
                if (data.code != 1) {
                    window.location.reload();
                }
            })
            setTimeout(function () {
                checkapp();
            }, 10000);
        }

        if (!Config.addtabs && Config.actionname != 'login' && Config.app_id && Config.nolog) {
            checkapp();
        }
        watermark.load({
            watermark_txt: Config.app_name + "," + Config.nickname + "," + Config.time,
            watermark_alpha: 0.01
        });
        require(['fast'], function (Fast) {
            require(['backend', 'backend-init', 'addons'], function (Backend, undefined, Addons) {
                //加载相应模块
                if (Config.jsname) {
                    require([Config.jsname], function (Controller) {
                        Controller[Config.actionname] != undefined && Controller[Config.actionname]();
                    }, function (e) {
                        console.error(e);
                        // 这里可捕获模块加载的错误
                    });
                }
            });
        });
    });
});

define("require-backend", function () {});

define('../libs/require-css/css.min', [], function () {
    if ("undefined" == typeof window) return {
        load: function (a, b, c) {
            c()
        }
    };
    var a = document.getElementsByTagName("head")[0],
        b = window.navigator.userAgent.match(/Trident\/([^ ;]*)|AppleWebKit\/([^ ;]*)|Opera\/([^ ;]*)|rv\:([^ ;]*)(.*?)Gecko\/([^ ;]*)|MSIE\s([^ ;]*)|AndroidWebKit\/([^ ;]*)/) || 0,
        c = !1,
        d = !0;
    b[1] || b[7] ? c = parseInt(b[1]) < 6 || parseInt(b[7]) <= 9 : b[2] || b[8] ? d = !1 : b[4] && (c = parseInt(b[4]) < 18);
    var e = {};
    e.pluginBuilder = "./css-builder";
    var f, g, h, i = function () {
            f = document.createElement("style"), a.appendChild(f), g = f.styleSheet || f.sheet
        },
        j = 0,
        k = [],
        l = function (a) {
            g.addImport(a), f.onload = function () {
                m()
            }, j++, 31 == j && (i(), j = 0)
        },
        m = function () {
            h();
            var a = k.shift();
            return a ? (h = a[1], void l(a[0])) : void(h = null)
        },
        n = function (a, b) {
            if (g && g.addImport || i(), g && g.addImport) h ? k.push([a, b]) : (l(a), h = b);
            else {
                f.textContent = '@import "' + a + '";';
                var c = setInterval(function () {
                    try {
                        f.sheet.cssRules, clearInterval(c), b()
                    } catch (a) {}
                }, 10)
            }
        },
        o = function (b, c) {
            var e = document.createElement("link");
            if (e.type = "text/css", e.rel = "stylesheet", d) e.onload = function () {
                e.onload = function () {}, setTimeout(c, 7)
            };
            else var f = setInterval(function () {
                for (var a = 0; a < document.styleSheets.length; a++) {
                    var b = document.styleSheets[a];
                    if (b.href == e.href) return clearInterval(f), c()
                }
            }, 10);
            e.href = b, a.appendChild(e)
        };
    return e.normalize = function (a, b) {
        return ".css" == a.substr(a.length - 4, 4) && (a = a.substr(0, a.length - 4)), b(a)
    }, e.load = function (a, b, d, e) {
        (c ? n : o)(b.toUrl(a + ".css"), d)
    }, e
});
/*! layer-v3.1.1 Web弹层组件 MIT License  http://layer.layui.com/  By 贤心 */
;
! function (e, t) {
    "use strict";
    var i, n, a = e.layui && layui.define,
        o = {
            getPath: function () {
                var e = document.currentScript ? document.currentScript.src : function () {
                    for (var e, t = document.scripts, i = t.length - 1, n = i; n > 0; n--)
                        if ("interactive" === t[n].readyState) {
                            e = t[n].src;
                            break
                        } return e || t[i].src
                }();
                return e.substring(0, e.lastIndexOf("/") + 1)
            }(),
            config: {},
            end: {},
            minIndex: 0,
            minLeft: [],
            btn: ["&#x786E;&#x5B9A;", "&#x53D6;&#x6D88;"],
            type: ["dialog", "page", "iframe", "loading", "tips"],
            getStyle: function (t, i) {
                var n = t.currentStyle ? t.currentStyle : e.getComputedStyle(t, null);
                return n[n.getPropertyValue ? "getPropertyValue" : "getAttribute"](i)
            },
            link: function (t, i, n) {
                if (r.path) {
                    var a = document.getElementsByTagName("head")[0],
                        s = document.createElement("link");
                    "string" == typeof i && (n = i);
                    var l = (n || t).replace(/\.|\//g, ""),
                        f = "layuicss-" + l,
                        c = 0;
                    s.rel = "stylesheet", s.href = r.path + t, s.id = f, document.getElementById(f) || a.appendChild(s), "function" == typeof i && ! function u() {
                        return ++c > 80 ? e.console && console.error("layer.css: Invalid") : void(1989 === parseInt(o.getStyle(document.getElementById(f), "width")) ? i() : setTimeout(u, 100))
                    }()
                }
            }
        },
        r = {
            v: "3.1.1",
            ie: function () {
                var t = navigator.userAgent.toLowerCase();
                return !!(e.ActiveXObject || "ActiveXObject" in e) && ((t.match(/msie\s(\d+)/) || [])[1] || "11")
            }(),
            index: e.layer && e.layer.v ? 1e5 : 0,
            path: o.getPath,
            config: function (e, t) {
                return e = e || {}, r.cache = o.config = i.extend({}, o.config, e), r.path = o.config.path || r.path, "string" == typeof e.extend && (e.extend = [e.extend]), o.config.path && r.ready(), e.extend ? (a ? layui.addcss("modules/layer/" + e.extend) : o.link("theme/" + e.extend), this) : this
            },
            ready: function (e) {
                var t = "layer",
                    i = "",
                    n = (a ? "modules/layer/" : "theme/") + "default/layer.css?v=" + r.v + i;
                return a ? layui.addcss(n, e, t) : o.link(n, e, t), this
            },
            alert: function (e, t, n) {
                var a = "function" == typeof t;
                return a && (n = t), r.open(i.extend({
                    content: e,
                    yes: n
                }, a ? {} : t))
            },
            confirm: function (e, t, n, a) {
                var s = "function" == typeof t;
                return s && (a = n, n = t), r.open(i.extend({
                    content: e,
                    btn: o.btn,
                    yes: n,
                    btn2: a
                }, s ? {} : t))
            },
            msg: function (e, n, a) {
                var s = "function" == typeof n,
                    f = o.config.skin,
                    c = (f ? f + " " + f + "-msg" : "") || "layui-layer-msg",
                    u = l.anim.length - 1;
                return s && (a = n), r.open(i.extend({
                    content: e,
                    time: 3e3,
                    shade: !1,
                    skin: c,
                    title: !1,
                    closeBtn: !1,
                    btn: !1,
                    resize: !1,
                    end: a
                }, s && !o.config.skin ? {
                    skin: c + " layui-layer-hui",
                    anim: u
                } : function () {
                    return n = n || {}, (n.icon === -1 || n.icon === t && !o.config.skin) && (n.skin = c + " " + (n.skin || "layui-layer-hui")), n
                }()))
            },
            load: function (e, t) {
                return r.open(i.extend({
                    type: 3,
                    icon: e || 0,
                    resize: !1,
                    shade: .01
                }, t))
            },
            tips: function (e, t, n) {
                return r.open(i.extend({
                    type: 4,
                    content: [e, t],
                    closeBtn: !1,
                    time: 3e3,
                    shade: !1,
                    resize: !1,
                    fixed: !1,
                    maxWidth: 210
                }, n))
            }
        },
        s = function (e) {
            var t = this;
            t.index = ++r.index, t.config = i.extend({}, t.config, o.config, e), document.body ? t.creat() : setTimeout(function () {
                t.creat()
            }, 30)
        };
    s.pt = s.prototype;
    var l = ["layui-layer", ".layui-layer-title", ".layui-layer-main", ".layui-layer-dialog", "layui-layer-iframe", "layui-layer-content", "layui-layer-btn", "layui-layer-close"];
    l.anim = ["layer-anim-00", "layer-anim-01", "layer-anim-02", "layer-anim-03", "layer-anim-04", "layer-anim-05", "layer-anim-06"], s.pt.config = {
        type: 0,
        shade: .3,
        fixed: !0,
        move: l[1],
        title: "&#x4FE1;&#x606F;",
        offset: "auto",
        area: "auto",
        closeBtn: 1,
        time: 0,
        zIndex: 19891014,
        maxWidth: 360,
        anim: 0,
        isOutAnim: !0,
        icon: -1,
        moveType: 1,
        resize: !0,
        scrollbar: !0,
        tips: 2
    }, s.pt.vessel = function (e, t) {
        var n = this,
            a = n.index,
            r = n.config,
            s = r.zIndex + a,
            f = "object" == typeof r.title,
            c = r.maxmin && (1 === r.type || 2 === r.type),
            u = r.title ? '<div class="layui-layer-title" style="' + (f ? r.title[1] : "") + '">' + (f ? r.title[0] : r.title) + "</div>" : "";
        return r.zIndex = s, t([r.shade ? '<div class="layui-layer-shade" id="layui-layer-shade' + a + '" times="' + a + '" style="' + ("z-index:" + (s - 1) + "; ") + '"></div>' : "", '<div class="' + l[0] + (" layui-layer-" + o.type[r.type]) + (0 != r.type && 2 != r.type || r.shade ? "" : " layui-layer-border") + " " + (r.skin || "") + '" id="' + l[0] + a + '" type="' + o.type[r.type] + '" times="' + a + '" showtime="' + r.time + '" conType="' + (e ? "object" : "string") + '" style="z-index: ' + s + "; width:" + r.area[0] + ";height:" + r.area[1] + (r.fixed ? "" : ";position:absolute;") + '">' + (e && 2 != r.type ? "" : u) + '<div id="' + (r.id || "") + '" class="layui-layer-content' + (0 == r.type && r.icon !== -1 ? " layui-layer-padding" : "") + (3 == r.type ? " layui-layer-loading" + r.icon : "") + '">' + (0 == r.type && r.icon !== -1 ? '<i class="layui-layer-ico layui-layer-ico' + r.icon + '"></i>' : "") + (1 == r.type && e ? "" : r.content || "") + '</div><span class="layui-layer-setwin">' + function () {
            var e = c ? '<a class="layui-layer-min" href="javascript:;"><cite></cite></a><a class="layui-layer-ico layui-layer-max" href="javascript:;"></a>' : "";
            return r.closeBtn && (e += '<a class="layui-layer-ico ' + l[7] + " " + l[7] + (r.title ? r.closeBtn : 4 == r.type ? "1" : "2") + '" href="javascript:;"></a>'), e
        }() + "</span>" + (r.btn ? function () {
            var e = "";
            "string" == typeof r.btn && (r.btn = [r.btn]);
            for (var t = 0, i = r.btn.length; t < i; t++) e += '<a class="' + l[6] + t + '">' + r.btn[t] + "</a>";
            return '<div class="' + l[6] + " layui-layer-btn-" + (r.btnAlign || "") + '">' + e + "</div>"
        }() : "") + (r.resize ? '<span class="layui-layer-resize"></span>' : "") + "</div>"], u, i('<div class="layui-layer-move"></div>')), n
    }, s.pt.creat = function () {
        var e = this,
            t = e.config,
            a = e.index,
            s = t.content,
            f = "object" == typeof s,
            c = i("body");
        if (!t.id || !i("#" + t.id)[0]) {
            switch ("string" == typeof t.area && (t.area = "auto" === t.area ? ["", ""] : [t.area, ""]), t.shift && (t.anim = t.shift), 6 == r.ie && (t.fixed = !1), t.type) {
                case 0:
                    t.btn = "btn" in t ? t.btn : o.btn[0], r.closeAll("dialog");
                    break;
                case 2:
                    var s = t.content = f ? t.content : [t.content || "http://layer.layui.com", "auto"];
                    t.content = '<iframe scrolling="' + (t.content[1] || "auto") + '" allowtransparency="true" id="' + l[4] + a + '" name="' + l[4] + a + '" onload="this.className=\'\';" class="layui-layer-load" frameborder="0" src="' + t.content[0] + '"></iframe>';
                    break;
                case 3:
                    delete t.title, delete t.closeBtn, t.icon === -1 && 0 === t.icon, r.closeAll("loading");
                    break;
                case 4:
                    f || (t.content = [t.content, "body"]), t.follow = t.content[1], t.content = t.content[0] + '<i class="layui-layer-TipsG"></i>', delete t.title, t.tips = "object" == typeof t.tips ? t.tips : [t.tips, !0], t.tipsMore || r.closeAll("tips")
            }
            if (e.vessel(f, function (n, r, u) {
                    c.append(n[0]), f ? function () {
                        2 == t.type || 4 == t.type ? function () {
                            i("body").append(n[1])
                        }() : function () {
                            s.parents("." + l[0])[0] || (s.data("display", s.css("display")).show().addClass("layui-layer-wrap").wrap(n[1]), i("#" + l[0] + a).find("." + l[5]).before(r))
                        }()
                    }() : c.append(n[1]), i(".layui-layer-move")[0] || c.append(o.moveElem = u), e.layero = i("#" + l[0] + a), t.scrollbar || l.html.css("overflow", "hidden").attr("layer-full", a)
                }).auto(a), i("#layui-layer-shade" + e.index).css({
                    "background-color": t.shade[1] || "#000",
                    opacity: t.shade[0] || t.shade
                }), 2 == t.type && 6 == r.ie && e.layero.find("iframe").attr("src", s[0]), 4 == t.type ? e.tips() : e.offset(), t.fixed && n.on("resize", function () {
                    e.offset(), (/^\d+%$/.test(t.area[0]) || /^\d+%$/.test(t.area[1])) && e.auto(a), 4 == t.type && e.tips()
                }), t.time <= 0 || setTimeout(function () {
                    r.close(e.index)
                }, t.time), e.move().callback(), l.anim[t.anim]) {
                var u = "layer-anim " + l.anim[t.anim];
                e.layero.addClass(u).one("webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend", function () {
                    i(this).removeClass(u)
                })
            }
            t.isOutAnim && e.layero.data("isOutAnim", !0)
        }
    }, s.pt.auto = function (e) {
        var t = this,
            a = t.config,
            o = i("#" + l[0] + e);
        "" === a.area[0] && a.maxWidth > 0 && (r.ie && r.ie < 8 && a.btn && o.width(o.innerWidth()), o.outerWidth() > a.maxWidth && o.width(a.maxWidth));
        var s = [o.innerWidth(), o.innerHeight()],
            f = o.find(l[1]).outerHeight() || 0,
            c = o.find("." + l[6]).outerHeight() || 0,
            u = function (e) {
                e = o.find(e), e.height(s[1] - f - c - 2 * (0 | parseFloat(e.css("padding-top"))))
            };
        switch (a.type) {
            case 2:
                u("iframe");
                break;
            default:
                "" === a.area[1] ? a.maxHeight > 0 && o.outerHeight() > a.maxHeight ? (s[1] = a.maxHeight, u("." + l[5])) : a.fixed && s[1] >= n.height() && (s[1] = n.height(), u("." + l[5])) : u("." + l[5])
        }
        return t
    }, s.pt.offset = function () {
        var e = this,
            t = e.config,
            i = e.layero,
            a = [i.outerWidth(), i.outerHeight()],
            o = "object" == typeof t.offset;
        e.offsetTop = (n.height() - a[1]) / 2, e.offsetLeft = (n.width() - a[0]) / 2, o ? (e.offsetTop = t.offset[0], e.offsetLeft = t.offset[1] || e.offsetLeft) : "auto" !== t.offset && ("t" === t.offset ? e.offsetTop = 0 : "r" === t.offset ? e.offsetLeft = n.width() - a[0] : "b" === t.offset ? e.offsetTop = n.height() - a[1] : "l" === t.offset ? e.offsetLeft = 0 : "lt" === t.offset ? (e.offsetTop = 0, e.offsetLeft = 0) : "lb" === t.offset ? (e.offsetTop = n.height() - a[1], e.offsetLeft = 0) : "rt" === t.offset ? (e.offsetTop = 0, e.offsetLeft = n.width() - a[0]) : "rb" === t.offset ? (e.offsetTop = n.height() - a[1], e.offsetLeft = n.width() - a[0]) : e.offsetTop = t.offset), t.fixed || (e.offsetTop = /%$/.test(e.offsetTop) ? n.height() * parseFloat(e.offsetTop) / 100 : parseFloat(e.offsetTop), e.offsetLeft = /%$/.test(e.offsetLeft) ? n.width() * parseFloat(e.offsetLeft) / 100 : parseFloat(e.offsetLeft), e.offsetTop += n.scrollTop(), e.offsetLeft += n.scrollLeft()), i.attr("minLeft") && (e.offsetTop = n.height() - (i.find(l[1]).outerHeight() || 0), e.offsetLeft = i.css("left")), i.css({
            top: e.offsetTop,
            left: e.offsetLeft
        })
    }, s.pt.tips = function () {
        var e = this,
            t = e.config,
            a = e.layero,
            o = [a.outerWidth(), a.outerHeight()],
            r = i(t.follow);
        r[0] || (r = i("body"));
        var s = {
                width: r.outerWidth(),
                height: r.outerHeight(),
                top: r.offset().top,
                left: r.offset().left
            },
            f = a.find(".layui-layer-TipsG"),
            c = t.tips[0];
        t.tips[1] || f.remove(), s.autoLeft = function () {
            s.left + o[0] - n.width() > 0 ? (s.tipLeft = s.left + s.width - o[0], f.css({
                right: 12,
                left: "auto"
            })) : s.tipLeft = s.left
        }, s.where = [function () {
            s.autoLeft(), s.tipTop = s.top - o[1] - 10, f.removeClass("layui-layer-TipsB").addClass("layui-layer-TipsT").css("border-right-color", t.tips[1])
        }, function () {
            s.tipLeft = s.left + s.width + 10, s.tipTop = s.top, f.removeClass("layui-layer-TipsL").addClass("layui-layer-TipsR").css("border-bottom-color", t.tips[1])
        }, function () {
            s.autoLeft(), s.tipTop = s.top + s.height + 10, f.removeClass("layui-layer-TipsT").addClass("layui-layer-TipsB").css("border-right-color", t.tips[1])
        }, function () {
            s.tipLeft = s.left - o[0] - 10, s.tipTop = s.top, f.removeClass("layui-layer-TipsR").addClass("layui-layer-TipsL").css("border-bottom-color", t.tips[1])
        }], s.where[c - 1](), 1 === c ? s.top - (n.scrollTop() + o[1] + 16) < 0 && s.where[2]() : 2 === c ? n.width() - (s.left + s.width + o[0] + 16) > 0 || s.where[3]() : 3 === c ? s.top - n.scrollTop() + s.height + o[1] + 16 - n.height() > 0 && s.where[0]() : 4 === c && o[0] + 16 - s.left > 0 && s.where[1](), a.find("." + l[5]).css({
            "background-color": t.tips[1],
            "padding-right": t.closeBtn ? "30px" : ""
        }), a.css({
            left: s.tipLeft - (t.fixed ? n.scrollLeft() : 0),
            top: s.tipTop - (t.fixed ? n.scrollTop() : 0)
        })
    }, s.pt.move = function () {
        var e = this,
            t = e.config,
            a = i(document),
            s = e.layero,
            l = s.find(t.move),
            f = s.find(".layui-layer-resize"),
            c = {};
        return t.move && l.css("cursor", "move"), l.on("mousedown", function (e) {
            e.preventDefault(), t.move && (c.moveStart = !0, c.offset = [e.clientX - parseFloat(s.css("left")), e.clientY - parseFloat(s.css("top"))], o.moveElem.css("cursor", "move").show())
        }), f.on("mousedown", function (e) {
            e.preventDefault(), c.resizeStart = !0, c.offset = [e.clientX, e.clientY], c.area = [s.outerWidth(), s.outerHeight()], o.moveElem.css("cursor", "se-resize").show()
        }), a.on("mousemove", function (i) {
            if (c.moveStart) {
                var a = i.clientX - c.offset[0],
                    o = i.clientY - c.offset[1],
                    l = "fixed" === s.css("position");
                if (i.preventDefault(), c.stX = l ? 0 : n.scrollLeft(), c.stY = l ? 0 : n.scrollTop(), !t.moveOut) {
                    var f = n.width() - s.outerWidth() + c.stX,
                        u = n.height() - s.outerHeight() + c.stY;
                    a < c.stX && (a = c.stX), a > f && (a = f), o < c.stY && (o = c.stY), o > u && (o = u)
                }
                s.css({
                    left: a,
                    top: o
                })
            }
            if (t.resize && c.resizeStart) {
                var a = i.clientX - c.offset[0],
                    o = i.clientY - c.offset[1];
                i.preventDefault(), r.style(e.index, {
                    width: c.area[0] + a,
                    height: c.area[1] + o
                }), c.isResize = !0, t.resizing && t.resizing(s)
            }
        }).on("mouseup", function (e) {
            c.moveStart && (delete c.moveStart, o.moveElem.hide(), t.moveEnd && t.moveEnd(s)), c.resizeStart && (delete c.resizeStart, o.moveElem.hide())
        }), e
    }, s.pt.callback = function () {
        function e() {
            var e = a.cancel && a.cancel(t.index, n);
            e === !1 || r.close(t.index)
        }
        var t = this,
            n = t.layero,
            a = t.config;
        t.openLayer(), a.success && (2 == a.type ? n.find("iframe").on("load", function () {
            a.success(n, t.index)
        }) : a.success(n, t.index)), 6 == r.ie && t.IE6(n), n.find("." + l[6]).children("a").on("click", function () {
            var e = i(this).index();
            if (0 === e) a.yes ? a.yes(t.index, n) : a.btn1 ? a.btn1(t.index, n) : r.close(t.index);
            else {
                var o = a["btn" + (e + 1)] && a["btn" + (e + 1)](t.index, n);
                o === !1 || r.close(t.index)
            }
        }), n.find("." + l[7]).on("click", e), a.shadeClose && i("#layui-layer-shade" + t.index).on("click", function () {
            r.close(t.index)
        }), n.find(".layui-layer-min").on("click", function () {
            var e = a.min && a.min(n);
            e === !1 || r.min(t.index, a)
        }), n.find(".layui-layer-max").on("click", function () {
            i(this).hasClass("layui-layer-maxmin") ? (r.restore(t.index), a.restore && a.restore(n)) : (r.full(t.index, a), setTimeout(function () {
                a.full && a.full(n)
            }, 100))
        }), a.end && (o.end[t.index] = a.end)
    }, o.reselect = function () {
        i.each(i("select"), function (e, t) {
            var n = i(this);
            n.parents("." + l[0])[0] || 1 == n.attr("layer") && i("." + l[0]).length < 1 && n.removeAttr("layer").show(), n = null
        })
    }, s.pt.IE6 = function (e) {
        i("select").each(function (e, t) {
            var n = i(this);
            n.parents("." + l[0])[0] || "none" === n.css("display") || n.attr({
                layer: "1"
            }).hide(), n = null
        })
    }, s.pt.openLayer = function () {
        var e = this;
        r.zIndex = e.config.zIndex, r.setTop = function (e) {
            var t = function () {
                r.zIndex++, e.css("z-index", r.zIndex + 1)
            };
            return r.zIndex = parseInt(e[0].style.zIndex), e.on("mousedown", t), r.zIndex
        }
    }, o.record = function (e) {
        var t = [e.width(), e.height(), e.position().top, e.position().left + parseFloat(e.css("margin-left"))];
        e.find(".layui-layer-max").addClass("layui-layer-maxmin"), e.attr({
            area: t
        })
    }, o.rescollbar = function (e) {
        l.html.attr("layer-full") == e && (l.html[0].style.removeProperty ? l.html[0].style.removeProperty("overflow") : l.html[0].style.removeAttribute("overflow"), l.html.removeAttr("layer-full"))
    }, e.layer = r, r.getChildFrame = function (e, t) {
        return t = t || i("." + l[4]).attr("times"), i("#" + l[0] + t).find("iframe").contents().find(e)
    }, r.getFrameIndex = function (e) {
        return i("#" + e).parents("." + l[4]).attr("times")
    }, r.iframeAuto = function (e) {
        if (e) {
            var t = r.getChildFrame("html", e).outerHeight(),
                n = i("#" + l[0] + e),
                a = n.find(l[1]).outerHeight() || 0,
                o = n.find("." + l[6]).outerHeight() || 0;
            n.css({
                height: t + a + o
            }), n.find("iframe").css({
                height: t
            })
        }
    }, r.iframeSrc = function (e, t) {
        i("#" + l[0] + e).find("iframe").attr("src", t)
    }, r.style = function (e, t, n) {
        var a = i("#" + l[0] + e),
            r = a.find(".layui-layer-content"),
            s = a.attr("type"),
            f = a.find(l[1]).outerHeight() || 0,
            c = a.find("." + l[6]).outerHeight() || 0;
        a.attr("minLeft");
        s !== o.type[3] && s !== o.type[4] && (n || (parseFloat(t.width) <= 260 && (t.width = 260), parseFloat(t.height) - f - c <= 64 && (t.height = 64 + f + c)), a.css(t), c = a.find("." + l[6]).outerHeight(), s === o.type[2] ? a.find("iframe").css({
            height: parseFloat(t.height) - f - c
        }) : r.css({
            height: parseFloat(t.height) - f - c - parseFloat(r.css("padding-top")) - parseFloat(r.css("padding-bottom"))
        }))
    }, r.min = function (e, t) {
        var a = i("#" + l[0] + e),
            s = a.find(l[1]).outerHeight() || 0,
            f = a.attr("minLeft") || 181 * o.minIndex + "px",
            c = a.css("position");
        o.record(a), o.minLeft[0] && (f = o.minLeft[0], o.minLeft.shift()), a.attr("position", c), r.style(e, {
            width: 180,
            height: s,
            left: f,
            top: n.height() - s,
            position: "fixed",
            overflow: "hidden"
        }, !0), a.find(".layui-layer-min").hide(), "page" === a.attr("type") && a.find(l[4]).hide(), o.rescollbar(e), a.attr("minLeft") || o.minIndex++, a.attr("minLeft", f)
    }, r.restore = function (e) {
        var t = i("#" + l[0] + e),
            n = t.attr("area").split(",");
        t.attr("type");
        r.style(e, {
            width: parseFloat(n[0]),
            height: parseFloat(n[1]),
            top: parseFloat(n[2]),
            left: parseFloat(n[3]),
            position: t.attr("position"),
            overflow: "visible"
        }, !0), t.find(".layui-layer-max").removeClass("layui-layer-maxmin"), t.find(".layui-layer-min").show(), "page" === t.attr("type") && t.find(l[4]).show(), o.rescollbar(e)
    }, r.full = function (e) {
        var t, a = i("#" + l[0] + e);
        o.record(a), l.html.attr("layer-full") || l.html.css("overflow", "hidden").attr("layer-full", e), clearTimeout(t), t = setTimeout(function () {
            var t = "fixed" === a.css("position");
            r.style(e, {
                top: t ? 0 : n.scrollTop(),
                left: t ? 0 : n.scrollLeft(),
                width: n.width(),
                height: n.height()
            }, !0), a.find(".layui-layer-min").hide()
        }, 100)
    }, r.title = function (e, t) {
        var n = i("#" + l[0] + (t || r.index)).find(l[1]);
        n.html(e)
    }, r.close = function (e) {
        var t = i("#" + l[0] + e),
            n = t.attr("type"),
            a = "layer-anim-close";
        if (t[0]) {
            var s = "layui-layer-wrap",
                f = function () {
                    if (n === o.type[1] && "object" === t.attr("conType")) {
                        t.children(":not(." + l[5] + ")").remove();
                        for (var a = t.find("." + s), r = 0; r < 2; r++) a.unwrap();
                        a.css("display", a.data("display")).removeClass(s)
                    } else {
                        if (n === o.type[2]) try {
                            var f = i("#" + l[4] + e)[0];
                            f.contentWindow.document.write(""), f.contentWindow.close(), t.find("." + l[5])[0].removeChild(f)
                        } catch (c) {}
                        t[0].innerHTML = "", t.remove()
                    }
                    "function" == typeof o.end[e] && o.end[e](), delete o.end[e]
                };
            t.data("isOutAnim") && t.addClass("layer-anim " + a), i("#layui-layer-moves, #layui-layer-shade" + e).remove(), 6 == r.ie && o.reselect(), o.rescollbar(e), t.attr("minLeft") && (o.minIndex--, o.minLeft.push(t.attr("minLeft"))), r.ie && r.ie < 10 || !t.data("isOutAnim") ? f() : setTimeout(function () {
                f()
            }, 200)
        }
    }, r.closeAll = function (e) {
        i.each(i("." + l[0]), function () {
            var t = i(this),
                n = e ? t.attr("type") === e : 1;
            n && r.close(t.attr("times")), n = null
        })
    };
    var f = r.cache || {},
        c = function (e) {
            return f.skin ? " " + f.skin + " " + f.skin + "-" + e : ""
        };
    r.prompt = function (e, t) {
        var a = "";
        if (e = e || {}, "function" == typeof e && (t = e), e.area) {
            var o = e.area;
            a = 'style="width: ' + o[0] + "; height: " + o[1] + ';"', delete e.area
        }
        var s, l = 2 == e.formType ? '<textarea class="layui-layer-input"' + a + ">" + (e.value || "") + "</textarea>" : function () {
                return '<input type="' + (1 == e.formType ? "password" : "text") + '" class="layui-layer-input" value="' + (e.value || "") + '">'
            }(),
            f = e.success;
        return delete e.success, r.open(i.extend({
            type: 1,
            btn: ["&#x786E;&#x5B9A;", "&#x53D6;&#x6D88;"],
            content: l,
            skin: "layui-layer-prompt" + c("prompt"),
            maxWidth: n.width(),
            success: function (e) {
                s = e.find(".layui-layer-input"), s.focus(), "function" == typeof f && f(e)
            },
            resize: !1,
            yes: function (i) {
                var n = s.val();
                "" === n ? s.focus() : n.length > (e.maxlength || 500) ? r.tips("&#x6700;&#x591A;&#x8F93;&#x5165;" + (e.maxlength || 500) + "&#x4E2A;&#x5B57;&#x6570;", s, {
                    tips: 1
                }) : t && t(n, i, s)
            }
        }, e))
    }, r.tab = function (e) {
        e = e || {};
        var t = e.tab || {},
            n = "layui-this",
            a = e.success;
        return delete e.success, r.open(i.extend({
            type: 1,
            skin: "layui-layer-tab" + c("tab"),
            resize: !1,
            title: function () {
                var e = t.length,
                    i = 1,
                    a = "";
                if (e > 0)
                    for (a = '<span class="' + n + '">' + t[0].title + "</span>"; i < e; i++) a += "<span>" + t[i].title + "</span>";
                return a
            }(),
            content: '<ul class="layui-layer-tabmain">' + function () {
                var e = t.length,
                    i = 1,
                    a = "";
                if (e > 0)
                    for (a = '<li class="layui-layer-tabli ' + n + '">' + (t[0].content || "no content") + "</li>"; i < e; i++) a += '<li class="layui-layer-tabli">' + (t[i].content || "no  content") + "</li>";
                return a
            }() + "</ul>",
            success: function (t) {
                var o = t.find(".layui-layer-title").children(),
                    r = t.find(".layui-layer-tabmain").children();
                o.on("mousedown", function (t) {
                    t.stopPropagation ? t.stopPropagation() : t.cancelBubble = !0;
                    var a = i(this),
                        o = a.index();
                    a.addClass(n).siblings().removeClass(n), r.eq(o).show().siblings().hide(), "function" == typeof e.change && e.change(o)
                }), "function" == typeof a && a(t)
            }
        }, e))
    }, r.photos = function (t, n, a) {
        function o(e, t, i) {
            var n = new Image;
            return n.src = e, n.complete ? t(n) : (n.onload = function () {
                n.onload = null, t(n)
            }, void(n.onerror = function (e) {
                n.onerror = null, i(e)
            }))
        }
        var s = {};
        if (t = t || {}, t.photos) {
            var l = t.photos.constructor === Object,
                f = l ? t.photos : {},
                u = f.data || [],
                d = f.start || 0;
            s.imgIndex = (0 | d) + 1, t.img = t.img || "img";
            var y = t.success;
            if (delete t.success, l) {
                if (0 === u.length) return r.msg("&#x6CA1;&#x6709;&#x56FE;&#x7247;")
            } else {
                var p = i(t.photos),
                    h = function () {
                        u = [], p.find(t.img).each(function (e) {
                            var t = i(this);
                            t.attr("layer-index", e), u.push({
                                alt: t.attr("alt"),
                                pid: t.attr("layer-pid"),
                                src: t.attr("layer-src") || t.attr("src"),
                                thumb: t.attr("src")
                            })
                        })
                    };
                if (h(), 0 === u.length) return;
                if (n || p.on("click", t.img, function () {
                        var e = i(this),
                            n = e.attr("layer-index");
                        r.photos(i.extend(t, {
                            photos: {
                                start: n,
                                data: u,
                                tab: t.tab
                            },
                            full: t.full
                        }), !0), h()
                    }), !n) return
            }
            s.imgprev = function (e) {
                s.imgIndex--, s.imgIndex < 1 && (s.imgIndex = u.length), s.tabimg(e)
            }, s.imgnext = function (e, t) {
                s.imgIndex++, s.imgIndex > u.length && (s.imgIndex = 1, t) || s.tabimg(e)
            }, s.keyup = function (e) {
                if (!s.end) {
                    var t = e.keyCode;
                    e.preventDefault(), 37 === t ? s.imgprev(!0) : 39 === t ? s.imgnext(!0) : 27 === t && r.close(s.index)
                }
            }, s.tabimg = function (e) {
                if (!(u.length <= 1)) return f.start = s.imgIndex - 1, r.close(s.index), r.photos(t, !0, e)
            }, s.event = function () {
                s.bigimg.hover(function () {
                    s.imgsee.show()
                }, function () {
                    s.imgsee.hide()
                }), s.bigimg.find(".layui-layer-imgprev").on("click", function (e) {
                    e.preventDefault(), s.imgprev()
                }), s.bigimg.find(".layui-layer-imgnext").on("click", function (e) {
                    e.preventDefault(), s.imgnext()
                }), i(document).on("keyup", s.keyup)
            }, s.loadi = r.load(1, {
                shade: !("shade" in t) && .9,
                scrollbar: !1
            }), o(u[d].src, function (n) {
                r.close(s.loadi), s.index = r.open(i.extend({
                    type: 1,
                    id: "layui-layer-photos",
                    area: function () {
                        var a = [n.width, n.height],
                            o = [i(e).width() - 100, i(e).height() - 100];
                        if (!t.full && (a[0] > o[0] || a[1] > o[1])) {
                            var r = [a[0] / o[0], a[1] / o[1]];
                            r[0] > r[1] ? (a[0] = a[0] / r[0], a[1] = a[1] / r[0]) : r[0] < r[1] && (a[0] = a[0] / r[1], a[1] = a[1] / r[1])
                        }
                        return [a[0] + "px", a[1] + "px"]
                    }(),
                    title: !1,
                    shade: .9,
                    shadeClose: !0,
                    closeBtn: !1,
                    move: ".layui-layer-phimg img",
                    moveType: 1,
                    scrollbar: !1,
                    moveOut: !0,
                    isOutAnim: !1,
                    skin: "layui-layer-photos" + c("photos"),
                    content: '<div class="layui-layer-phimg"><img src="' + u[d].src + '" alt="' + (u[d].alt || "") + '" layer-pid="' + u[d].pid + '"><div class="layui-layer-imgsee">' + (u.length > 1 ? '<span class="layui-layer-imguide"><a href="javascript:;" class="layui-layer-iconext layui-layer-imgprev"></a><a href="javascript:;" class="layui-layer-iconext layui-layer-imgnext"></a></span>' : "") + '<div class="layui-layer-imgbar" style="display:' + (a ? "block" : "") + '"><span class="layui-layer-imgtit"><a href="javascript:;">' + (u[d].alt || "") + "</a><em>" + s.imgIndex + "/" + u.length + "</em></span></div></div></div>",
                    success: function (e, i) {
                        s.bigimg = e.find(".layui-layer-phimg"), s.imgsee = e.find(".layui-layer-imguide,.layui-layer-imgbar"), s.event(e), t.tab && t.tab(u[d], e), "function" == typeof y && y(e)
                    },
                    end: function () {
                        s.end = !0, i(document).off("keyup", s.keyup)
                    }
                }, t))
            }, function () {
                r.close(s.loadi), r.msg("&#x5F53;&#x524D;&#x56FE;&#x7247;&#x5730;&#x5740;&#x5F02;&#x5E38;<br>&#x662F;&#x5426;&#x7EE7;&#x7EED;&#x67E5;&#x770B;&#x4E0B;&#x4E00;&#x5F20;&#xFF1F;", {
                    time: 3e4,
                    btn: ["&#x4E0B;&#x4E00;&#x5F20;", "&#x4E0D;&#x770B;&#x4E86;"],
                    yes: function () {
                        u.length > 1 && s.imgnext(!0, !0)
                    }
                })
            })
        }
    }, o.run = function (t) {
        i = t, n = i(e), l.html = i("html"), r.open = function (e) {
            var t = new s(e);
            return t.index
        }
    }, e.layui && layui.define ? (r.ready(), layui.define("jquery", function (t) {
        r.path = layui.cache.dir, o.run(layui.$), e.layer = r, t("layer", r)
    })) : "function" == typeof define && define.amd ? define('layer', ["jquery"], function () {
        return o.run(e.jQuery), r
    }) : function () {
        o.run(e.jQuery), r.ready()
    }()
}(window);
/*
 * Toastr
 * Copyright 2012-2015
 * Authors: John Papa, Hans Fjällemark, and Tim Ferrell.
 * All Rights Reserved.
 * Use, reproduction, distribution, and modification of this code is subject to the terms and
 * conditions of the MIT license, available at http://www.opensource.org/licenses/mit-license.php
 *
 * ARIA Support: Greta Krafsig
 *
 * Project: https://github.com/CodeSeven/toastr
 */
/* global define */
(function (define) {
    define('toastr', ['jquery'], function ($) {
        return (function () {
            var $container;
            var listener;
            var toastId = 0;
            var toastType = {
                error: 'error',
                info: 'info',
                success: 'success',
                warning: 'warning'
            };

            var toastr = {
                clear: clear,
                remove: remove,
                error: error,
                getContainer: getContainer,
                info: info,
                options: {},
                subscribe: subscribe,
                success: success,
                version: '2.1.3',
                warning: warning
            };

            var previousToast;

            return toastr;

            ////////////////

            function error(message, title, optionsOverride) {
                return notify({
                    type: toastType.error,
                    iconClass: getOptions().iconClasses.error,
                    message: message,
                    optionsOverride: optionsOverride,
                    title: title
                });
            }

            function getContainer(options, create) {
                if (!options) {
                    options = getOptions();
                }
                $container = $('#' + options.containerId);
                if ($container.length) {
                    return $container;
                }
                if (create) {
                    $container = createContainer(options);
                }
                return $container;
            }

            function info(message, title, optionsOverride) {
                return notify({
                    type: toastType.info,
                    iconClass: getOptions().iconClasses.info,
                    message: message,
                    optionsOverride: optionsOverride,
                    title: title
                });
            }

            function subscribe(callback) {
                listener = callback;
            }

            function success(message, title, optionsOverride) {
                return notify({
                    type: toastType.success,
                    iconClass: getOptions().iconClasses.success,
                    message: message,
                    optionsOverride: optionsOverride,
                    title: title
                });
            }

            function warning(message, title, optionsOverride) {
                return notify({
                    type: toastType.warning,
                    iconClass: getOptions().iconClasses.warning,
                    message: message,
                    optionsOverride: optionsOverride,
                    title: title
                });
            }

            function clear($toastElement, clearOptions) {
                var options = getOptions();
                if (!$container) {
                    getContainer(options);
                }
                if (!clearToast($toastElement, options, clearOptions)) {
                    clearContainer(options);
                }
            }

            function remove($toastElement) {
                var options = getOptions();
                if (!$container) {
                    getContainer(options);
                }
                if ($toastElement && $(':focus', $toastElement).length === 0) {
                    removeToast($toastElement);
                    return;
                }
                if ($container.children().length) {
                    $container.remove();
                }
            }

            // internal functions

            function clearContainer(options) {
                var toastsToClear = $container.children();
                for (var i = toastsToClear.length - 1; i >= 0; i--) {
                    clearToast($(toastsToClear[i]), options);
                }
            }

            function clearToast($toastElement, options, clearOptions) {
                var force = clearOptions && clearOptions.force ? clearOptions.force : false;
                if ($toastElement && (force || $(':focus', $toastElement).length === 0)) {
                    $toastElement[options.hideMethod]({
                        duration: options.hideDuration,
                        easing: options.hideEasing,
                        complete: function () {
                            removeToast($toastElement);
                        }
                    });
                    return true;
                }
                return false;
            }

            function createContainer(options) {
                $container = $('<div/>')
                    .attr('id', options.containerId)
                    .addClass(options.positionClass);

                $container.appendTo($(options.target));
                return $container;
            }

            function getDefaults() {
                return {
                    tapToDismiss: true,
                    toastClass: 'toast',
                    containerId: 'toast-container',
                    debug: false,

                    showMethod: 'fadeIn', //fadeIn, slideDown, and show are built into jQuery
                    showDuration: 300,
                    showEasing: 'swing', //swing and linear are built into jQuery
                    onShown: undefined,
                    hideMethod: 'fadeOut',
                    hideDuration: 1000,
                    hideEasing: 'swing',
                    onHidden: undefined,
                    closeMethod: false,
                    closeDuration: false,
                    closeEasing: false,
                    closeOnHover: true,

                    extendedTimeOut: 1000,
                    iconClasses: {
                        error: 'toast-error',
                        info: 'toast-info',
                        success: 'toast-success',
                        warning: 'toast-warning'
                    },
                    iconClass: 'toast-info',
                    positionClass: 'toast-top-right',
                    timeOut: 5000, // Set timeOut and extendedTimeOut to 0 to make it sticky
                    titleClass: 'toast-title',
                    messageClass: 'toast-message',
                    escapeHtml: false,
                    target: 'body',
                    closeHtml: '<button type="button">&times;</button>',
                    closeClass: 'toast-close-button',
                    newestOnTop: true,
                    preventDuplicates: false,
                    progressBar: false,
                    progressClass: 'toast-progress',
                    rtl: false
                };
            }

            function publish(args) {
                if (!listener) {
                    return;
                }
                listener(args);
            }

            function notify(map) {
                var options = getOptions();
                var iconClass = map.iconClass || options.iconClass;

                if (typeof (map.optionsOverride) !== 'undefined') {
                    options = $.extend(options, map.optionsOverride);
                    iconClass = map.optionsOverride.iconClass || iconClass;
                }

                if (shouldExit(options, map)) {
                    return;
                }

                toastId++;

                $container = getContainer(options, true);

                var intervalId = null;
                var $toastElement = $('<div/>');
                var $titleElement = $('<div/>');
                var $messageElement = $('<div/>');
                var $progressElement = $('<div/>');
                var $closeElement = $(options.closeHtml);
                var progressBar = {
                    intervalId: null,
                    hideEta: null,
                    maxHideTime: null
                };
                var response = {
                    toastId: toastId,
                    state: 'visible',
                    startTime: new Date(),
                    options: options,
                    map: map
                };

                personalizeToast();

                displayToast();

                handleEvents();

                publish(response);

                if (options.debug && console) {
                    console.log(response);
                }

                return $toastElement;

                function escapeHtml(source) {
                    if (source == null) {
                        source = '';
                    }

                    return source
                        .replace(/&/g, '&amp;')
                        .replace(/"/g, '&quot;')
                        .replace(/'/g, '&#39;')
                        .replace(/</g, '&lt;')
                        .replace(/>/g, '&gt;');
                }

                function personalizeToast() {
                    setIcon();
                    setTitle();
                    setMessage();
                    setCloseButton();
                    setProgressBar();
                    setRTL();
                    setSequence();
                    setAria();
                }

                function setAria() {
                    var ariaValue = '';
                    switch (map.iconClass) {
                        case 'toast-success':
                        case 'toast-info':
                            ariaValue = 'polite';
                            break;
                        default:
                            ariaValue = 'assertive';
                    }
                    $toastElement.attr('aria-live', ariaValue);
                }

                function handleEvents() {
                    if (options.closeOnHover) {
                        $toastElement.hover(stickAround, delayedHideToast);
                    }

                    if (!options.onclick && options.tapToDismiss) {
                        $toastElement.click(hideToast);
                    }

                    if (options.closeButton && $closeElement) {
                        $closeElement.click(function (event) {
                            if (event.stopPropagation) {
                                event.stopPropagation();
                            } else if (event.cancelBubble !== undefined && event.cancelBubble !== true) {
                                event.cancelBubble = true;
                            }

                            if (options.onCloseClick) {
                                options.onCloseClick(event);
                            }

                            hideToast(true);
                        });
                    }

                    if (options.onclick) {
                        $toastElement.click(function (event) {
                            options.onclick(event);
                            hideToast();
                        });
                    }
                }

                function displayToast() {
                    $toastElement.hide();

                    $toastElement[options.showMethod]({
                        duration: options.showDuration,
                        easing: options.showEasing,
                        complete: options.onShown
                    });

                    if (options.timeOut > 0) {
                        intervalId = setTimeout(hideToast, options.timeOut);
                        progressBar.maxHideTime = parseFloat(options.timeOut);
                        progressBar.hideEta = new Date().getTime() + progressBar.maxHideTime;
                        if (options.progressBar) {
                            progressBar.intervalId = setInterval(updateProgress, 10);
                        }
                    }
                }

                function setIcon() {
                    if (map.iconClass) {
                        $toastElement.addClass(options.toastClass).addClass(iconClass);
                    }
                }

                function setSequence() {
                    if (options.newestOnTop) {
                        $container.prepend($toastElement);
                    } else {
                        $container.append($toastElement);
                    }
                }

                function setTitle() {
                    if (map.title) {
                        var suffix = map.title;
                        if (options.escapeHtml) {
                            suffix = escapeHtml(map.title);
                        }
                        $titleElement.append(suffix).addClass(options.titleClass);
                        $toastElement.append($titleElement);
                    }
                }

                function setMessage() {
                    if (map.message) {
                        var suffix = map.message;
                        if (options.escapeHtml) {
                            suffix = escapeHtml(map.message);
                        }
                        $messageElement.append(suffix).addClass(options.messageClass);
                        $toastElement.append($messageElement);
                    }
                }

                function setCloseButton() {
                    if (options.closeButton) {
                        $closeElement.addClass(options.closeClass).attr('role', 'button');
                        $toastElement.prepend($closeElement);
                    }
                }

                function setProgressBar() {
                    if (options.progressBar) {
                        $progressElement.addClass(options.progressClass);
                        $toastElement.prepend($progressElement);
                    }
                }

                function setRTL() {
                    if (options.rtl) {
                        $toastElement.addClass('rtl');
                    }
                }

                function shouldExit(options, map) {
                    if (options.preventDuplicates) {
                        if (map.message === previousToast) {
                            return true;
                        } else {
                            previousToast = map.message;
                        }
                    }
                    return false;
                }

                function hideToast(override) {
                    var method = override && options.closeMethod !== false ? options.closeMethod : options.hideMethod;
                    var duration = override && options.closeDuration !== false ?
                        options.closeDuration : options.hideDuration;
                    var easing = override && options.closeEasing !== false ? options.closeEasing : options.hideEasing;
                    if ($(':focus', $toastElement).length && !override) {
                        return;
                    }
                    clearTimeout(progressBar.intervalId);
                    return $toastElement[method]({
                        duration: duration,
                        easing: easing,
                        complete: function () {
                            removeToast($toastElement);
                            clearTimeout(intervalId);
                            if (options.onHidden && response.state !== 'hidden') {
                                options.onHidden();
                            }
                            response.state = 'hidden';
                            response.endTime = new Date();
                            publish(response);
                        }
                    });
                }

                function delayedHideToast() {
                    if (options.timeOut > 0 || options.extendedTimeOut > 0) {
                        intervalId = setTimeout(hideToast, options.extendedTimeOut);
                        progressBar.maxHideTime = parseFloat(options.extendedTimeOut);
                        progressBar.hideEta = new Date().getTime() + progressBar.maxHideTime;
                    }
                }

                function stickAround() {
                    clearTimeout(intervalId);
                    progressBar.hideEta = 0;
                    $toastElement.stop(true, true)[options.showMethod]({
                        duration: options.showDuration,
                        easing: options.showEasing
                    });
                }

                function updateProgress() {
                    var percentage = ((progressBar.hideEta - (new Date().getTime())) / progressBar.maxHideTime) * 100;
                    $progressElement.width(percentage + '%');
                }
            }

            function getOptions() {
                return $.extend({}, getDefaults(), toastr.options);
            }

            function removeToast($toastElement) {
                if (!$container) {
                    $container = getContainer();
                }
                if ($toastElement.is(':visible')) {
                    return;
                }
                $toastElement.remove();
                $toastElement = null;
                if ($container.children().length === 0) {
                    $container.remove();
                    previousToast = undefined;
                }
            }

        })();
    });
}(typeof define === 'function' && define.amd ? define : function (deps, factory) {
    if (typeof module !== 'undefined' && module.exports) { //Node
        module.exports = factory(require('jquery'));
    } else {
        window.toastr = factory(window.jQuery);
    }
}));

define('fast', ['jquery', 'bootstrap', 'toastr', 'layer', 'lang'], function ($, undefined, Toastr, Layer, Lang) {
    var Fast = {
        config: {
            //toastr默认配置
            toastr: {
                "closeButton": true,
                "debug": false,
                "newestOnTop": false,
                "progressBar": false,
                "positionClass": "toast-top-center",
                "preventDuplicates": false,
                "onclick": null,
                "showDuration": "300",
                "hideDuration": "1000",
                "timeOut": "5000",
                "extendedTimeOut": "1000",
                "showEasing": "swing",
                "hideEasing": "linear",
                "showMethod": "fadeIn",
                "hideMethod": "fadeOut"
            }
        },
        events: {
            //请求成功的回调
            onAjaxSuccess: function (ret, onAjaxSuccess) {
                var data = typeof ret.data !== 'undefined' ? ret.data : null;
                var msg = typeof ret.msg !== 'undefined' && ret.msg ? ret.msg : __('Operation completed');

                if (typeof onAjaxSuccess === 'function') {
                    var result = onAjaxSuccess.call(this, data, ret);
                    if (result === false)
                        return;
                }
                Toastr.success(msg);
            },
            //请求错误的回调
            onAjaxError: function (ret, onAjaxError) {
                var data = typeof ret.data !== 'undefined' ? ret.data : null;
                if (typeof onAjaxError === 'function') {
                    var result = onAjaxError.call(this, data, ret);
                    if (result === false) {
                        return;
                    }
                }
                Toastr.error(ret.msg);
            },
            //服务器响应数据后
            onAjaxResponse: function (response) {
                try {
                    var ret = typeof response === 'object' ? response : JSON.parse(response);
                    if (!ret.hasOwnProperty('code')) {
                        $.extend(ret, {
                            code: -2,
                            msg: response,
                            data: null
                        });
                    }
                } catch (e) {
                    var ret = {
                        code: -1,
                        msg: e.message,
                        data: null
                    };
                }
                return ret;
            }
        },
        api: {
            //发送Ajax请求
            ajax: function (options, success, error) {
                options = typeof options === 'string' ? {
                    url: options
                } : options;
                var index = Layer.load();
                options = $.extend({
                    type: "POST",
                    dataType: "json",
                    success: function (ret) {
                        //全局 拦截
                        if (ret.code === -9) {
                            window.location.replace(ret.url);
                            return false;
                        }
                        Layer.close(index);
                        ret = Fast.events.onAjaxResponse(ret);
                        if (ret.code === 1) {
                            Fast.events.onAjaxSuccess(ret, success);
                        } else {
                            Fast.events.onAjaxError(ret, error);
                        }
                    },
                    error: function (xhr) {
                        Layer.close(index);
                        var ret = {
                            code: xhr.status,
                            msg: xhr.statusText,
                            data: null
                        };
                        Fast.events.onAjaxError(ret, error);
                    }
                }, options);
                $.ajax(options);
            },
            //修复URL
            fixurl: function (url) {
                if (url.substr(0, 1) !== "/") {
                    var r = new RegExp('^(?:[a-z]+:)?//', 'i');
                    if (!r.test(url)) {
                        url = Config.moduleurl + "/" + url;
                    }
                } else if (url.substr(0, 8) === "/addons/") {
                    url = Config.__PUBLIC__.replace(/(\/*$)/g, "") + url;
                }
                return url;
            },
            //获取修复后可访问的cdn链接
            cdnurl: function (url, domain) {
                var rule = new RegExp("^((?:[a-z]+:)?\\/\\/|data:image\\/)", "i");
                var cdnurl = Config.upload.cdnurl;
                console.log(cdnurl, domain);
                if (typeof domain === 'undefined' || domain === true || cdnurl.indexOf("/") === 0) {
                    url = rule.test(url) || (cdnurl && url.indexOf(cdnurl) === 0) ? url : cdnurl + url;
                }
                if (domain && !rule.test(url)) {
                    domain = typeof domain === 'string' ? domain : location.origin;
                    url = domain + url;
                }
                return url;
            },
            //查询Url参数
            query: function (name, url) {
                if (!url) {
                    url = window.location.href;
                }
                name = name.replace(/[\[\]]/g, "\\$&");
                var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
                    results = regex.exec(url);
                if (!results)
                    return null;
                if (!results[2])
                    return '';
                return decodeURIComponent(results[2].replace(/\+/g, " "));
            },
            closeDtkLoading: function (callback) {
                callback && callback();
            }, // 关闭loading (仅dtk商品转入可用)
            checkDtkGoods: function (callback) { // 大淘客商品转入检测并自动执行callback
                const getUrlParam = function (name) {
                    const r = window.location.search.substr(1).match(new RegExp("(^|&)" + name + "=([^&]*)(&|$)"));
                    if (r != null) return unescape(r[2]);
                    return null;
                };
                const fromGoods = getUrlParam('from');
                // let goodsID = parseInt(getUrlParam('dtk_goodId'));
                let goodsID = getUrlParam('dtk_goodId');

                //if (isNaN(goodsID)) goodsID = 0;
                if (fromGoods === "dtk_goods" && goodsID) {
                    const loadingIdx = layer.load(1, {
                        shade: [0.1, '#000']
                    });
                    try {
                        var dtkData = JSON.parse(decodeURIComponent(window.atob(getUrlParam('dtk_data'))));
                    } catch (e) {
                        var dtkData = {};
                    }
                    dtkData['loadingIdx'] = loadingIdx
                    callback && callback(goodsID, dtkData.tip, dtkData);
                    Fast.api.closeDtkLoading = function (callback) {
                        layer.close(loadingIdx);
                        callback && callback();
                    };
                    setTimeout(Fast.api.closeDtkLoading, 3000); // 补偿异常可能无法关闭loading
                }
            },
            //打开一个弹出窗口
            open: function (url, title, options) {
                title = title ? title : "";
                url = Fast.api.fixurl(url);
                url = url + (url.indexOf("?") > -1 ? "&" : "?") + "dialog=1";
                var area = [$(window).width() > 1000 ? '1000px' : '95%', $(window).height() > 600 ? '600px' : '98%'];
                options = $.extend({
                    type: 2,
                    title: title,
                    shadeClose: true,
                    shade: false,
                    maxmin: true,
                    moveOut: true,
                    area: area,
                    content: url,
                    zIndex: Layer.zIndex,
                    success: function (layero, index) {
                        var that = this;
                        //存储callback事件
                        $(layero).data("callback", that.callback);
                        //$(layero).removeClass("layui-layer-border");
                        Layer.setTop(layero);
                        try {
                            var frame = Layer.getChildFrame('html', index);
                            var layerfooter = frame.find(".layer-footer");
                            Fast.api.layerfooter(layero, index, that);
                            //绑定事件
                            if (layerfooter.size() > 0) {
                                // 监听窗口内的元素及属性变化
                                // Firefox和Chrome早期版本中带有前缀
                                var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
                                if (MutationObserver) {
                                    // 选择目标节点
                                    var target = layerfooter[0];
                                    // 创建观察者对象
                                    var observer = new MutationObserver(function (mutations) {
                                        Fast.api.layerfooter(layero, index, that);
                                        mutations.forEach(function (mutation) {});
                                    });
                                    // 配置观察选项:
                                    var config = {
                                        attributes: true,
                                        childList: true,
                                        characterData: true,
                                        subtree: true
                                    }
                                    // 传入目标节点和观察选项
                                    observer.observe(target, config);
                                    // 随后,你还可以停止观察
                                    // observer.disconnect();
                                }
                            }
                        } catch (e) {

                        }
                        if ($(layero).height() > $(window).height()) {
                            //当弹出窗口大于浏览器可视高度时,重定位
                            Layer.style(index, {
                                top: 0,
                                height: $(window).height()
                            });
                        }
                    }
                }, options ? options : {});
                if ($(window).width() < 480 || (/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream && top.$(".tab-pane.active").size() > 0)) {
                    var n = navigator.userAgent;
                    if (n.indexOf('iPhone') > -1) {
                        options.area = [top.$(".tab-pane.active").width() + "px", (top.$(".tab-pane.active").height() * 0.9) + "px"];
                    } else {
                        options.area = [top.$(".tab-pane.active").width() + "px", top.$(".tab-pane.active").height() + "px"];
                    }
                    options.offset = [top.$(".tab-pane.active").scrollTop() + "px", "0px"];
                }
                return Layer.open(options);
            },
            //关闭窗口并回传数据
            close: function (data) {
                var index = parent.Layer.getFrameIndex(window.name);
                var callback = parent.$("#layui-layer" + index).data("callback");
                //再执行关闭
                parent.Layer.close(index);
                //再调用回传函数
                if (typeof callback === 'function') {
                    callback.call(undefined, data);
                }
            },
            layerfooter: function (layero, index, that) {
                var frame = Layer.getChildFrame('html', index);
                var layerfooter = frame.find(".layer-footer");
                if (layerfooter.size() > 0) {
                    $(".layui-layer-footer", layero).remove();
                    var footer = $("<div />").addClass('layui-layer-btn layui-layer-footer');
                    footer.html(layerfooter.html());
                    if ($(".row", footer).size() === 0) {
                        $(">", footer).wrapAll("<div class='row'></div>");
                    }
                    footer.insertAfter(layero.find('.layui-layer-content'));
                    //绑定事件
                    footer.on("click", ".btn", function () {
                        if ($(this).hasClass("disabled") || $(this).parent().hasClass("disabled")) {
                            return;
                        }
                        $(".btn:eq(" + $(this).index() + ")", layerfooter).trigger("click");
                    });

                    var titHeight = layero.find('.layui-layer-title').outerHeight() || 0;
                    var btnHeight = layero.find('.layui-layer-btn').outerHeight() || 0;
                    //重设iframe高度
                    $("iframe", layero).height(layero.height() - titHeight - btnHeight);
                }
                //修复iOS下弹出窗口的高度和iOS下iframe无法滚动的BUG
                if (/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream) {
                    var titHeight = layero.find('.layui-layer-title').outerHeight() || 0;
                    var btnHeight = layero.find('.layui-layer-btn').outerHeight() || 0;
                    $("iframe", layero).parent().css("height", layero.height() - titHeight - btnHeight);
                    $("iframe", layero).css("height", "100%");
                }
            },
            success: function (options, callback) {
                var type = typeof options === 'function';
                if (type) {
                    callback = options;
                }
                return Layer.msg(__('Operation completed'), $.extend({
                    offset: 0,
                    icon: 1
                }, type ? {} : options), callback);
            },
            error: function (options, callback) {
                var type = typeof options === 'function';
                if (type) {
                    callback = options;
                }
                return Layer.msg(__('Operation failed'), $.extend({
                    offset: 0,
                    icon: 2
                }, type ? {} : options), callback);
            },
            toastr: Toastr,
            layer: Layer
        },
        lang: function () {
            var args = arguments,
                string = args[0],
                i = 1;
            string = string.toLowerCase();
            //string = typeof Lang[string] != 'undefined' ? Lang[string] : string;
            if (typeof Lang[string] != 'undefined') {
                if (typeof Lang[string] == 'object')
                    return Lang[string];
                string = Lang[string];
            } else if (string.indexOf('.') !== -1 && false) {
                var arr = string.split('.');
                var current = Lang[arr[0]];
                for (var i = 1; i < arr.length; i++) {
                    current = typeof current[arr[i]] != 'undefined' ? current[arr[i]] : '';
                    if (typeof current != 'object')
                        break;
                }
                if (typeof current == 'object')
                    return current;
                string = current;
            } else {
                string = args[0];
            }
            return string.replace(/%((%)|s|d)/g, function (m) {
                // m is the matched format, e.g. %s, %d
                var val = null;
                if (m[2]) {
                    val = m[2];
                } else {
                    val = args[i];
                    // A switch statement so that the formatter can be extended. Default is %s
                    switch (m) {
                        case '%d':
                            val = parseFloat(val);
                            if (isNaN(val)) {
                                val = 0;
                            }
                            break;
                    }
                    i++;
                }
                return val;
            });
        },
        init: function () {
            // 对相对地址进行处理
            $.ajaxSetup({
                beforeSend: function (xhr, setting) {
                    setting.url = Fast.api.fixurl(setting.url);
                }
            });
            Layer.config({
                skin: 'layui-layer-fast'
            });
            // 绑定ESC关闭窗口事件
            $(window).keyup(function (e) {
                if (e.keyCode == 27) {
                    if ($(".layui-layer").size() > 0) {
                        var index = 0;
                        $(".layui-layer").each(function () {
                            index = Math.max(index, parseInt($(this).attr("times")));
                        });
                        if (index) {
                            Layer.close(index);
                        }
                    }
                }
            });

            //公共代码
            //配置Toastr的参数
            Toastr.options = Fast.config.toastr;
        }
    };
    //将Layer暴露到全局中去
    window.Layer = Layer;
    //将Toastr暴露到全局中去
    window.Toastr = Toastr;
    //将语言方法暴露到全局中去
    window.__ = Fast.lang;
    //将Fast渲染至全局
    window.Fast = Fast;
    //默认初始化执行的代码
    Fast.init();
    return Fast;
});

/*!art-template - Template Engine | http://aui.github.com/artTemplate/*/
! function () {
    function a(a) {
        return a.replace(t, "").replace(u, ",").replace(v, "").replace(w, "").replace(x, "").split(y)
    }

    function b(a) {
        return "'" + a.replace(/('|\\)/g, "\\$1").replace(/\r/g, "\\r").replace(/\n/g, "\\n") + "'"
    }

    function c(c, d) {
        function e(a) {
            return m += a.split(/\n/).length - 1, k && (a = a.replace(/\s+/g, " ").replace(/<!--[\w\W]*?-->/g, "")), a && (a = s[1] + b(a) + s[2] + "\n"), a
        }

        function f(b) {
            var c = m;
            if (j ? b = j(b, d) : g && (b = b.replace(/\n/g, function () {
                    return m++, "$line=" + m + ";"
                })), 0 === b.indexOf("=")) {
                var e = l && !/^=[=#]/.test(b);
                if (b = b.replace(/^=[=#]?|[\s;]*$/g, ""), e) {
                    var f = b.replace(/\s*\([^\)]+\)/, "");
                    n[f] || /^(include|print)$/.test(f) || (b = "$escape(" + b + ")")
                } else b = "$string(" + b + ")";
                b = s[1] + b + s[2]
            }
            return g && (b = "$line=" + c + ";" + b), r(a(b), function (a) {
                if (a && !p[a]) {
                    var b;
                    b = "print" === a ? u : "include" === a ? v : n[a] ? "$utils." + a : o[a] ? "$helpers." + a : "$data." + a, w += a + "=" + b + ",", p[a] = !0
                }
            }), b + "\n"
        }
        var g = d.debug,
            h = d.openTag,
            i = d.closeTag,
            j = d.parser,
            k = d.compress,
            l = d.escape,
            m = 1,
            p = {
                $data: 1,
                $filename: 1,
                $utils: 1,
                $helpers: 1,
                $out: 1,
                $line: 1
            },
            q = "".trim,
            s = q ? ["$out='';", "$out+=", ";", "$out"] : ["$out=[];", "$out.push(", ");", "$out.join('')"],
            t = q ? "$out+=text;return $out;" : "$out.push(text);",
            u = "function(){var text=''.concat.apply('',arguments);" + t + "}",
            v = "function(filename,data){data=data||$data;var text=$utils.$include(filename,data,$filename);" + t + "}",
            w = "'use strict';var $utils=this,$helpers=$utils.$helpers," + (g ? "$line=0," : ""),
            x = s[0],
            y = "return new String(" + s[3] + ");";
        r(c.split(h), function (a) {
            a = a.split(i);
            var b = a[0],
                c = a[1];
            1 === a.length ? x += e(b) : (x += f(b), c && (x += e(c)))
        });
        var z = w + x + y;
        g && (z = "try{" + z + "}catch(e){throw {filename:$filename,name:'Render Error',message:e.message,line:$line,source:" + b(c) + ".split(/\\n/)[$line-1].replace(/^\\s+/,'')};}");
        try {
            var A = new Function("$data", "$filename", z);
            return A.prototype = n, A
        } catch (a) {
            throw a.temp = "function anonymous($data,$filename) {" + z + "}", a
        }
    }
    var d = function (a, b) {
        return "string" == typeof b ? q(b, {
            filename: a
        }) : g(a, b)
    };
    d.version = "3.0.0", d.config = function (a, b) {
        e[a] = b
    };
    var e = d.defaults = {
            openTag: "<%",
            closeTag: "%>",
            escape: !0,
            cache: !0,
            compress: !1,
            parser: null
        },
        f = d.cache = {};
    d.render = function (a, b) {
        return q(a)(b)
    };
    var g = d.renderFile = function (a, b) {
        var c = d.get(a) || p({
            filename: a,
            name: "Render Error",
            message: "Template not found"
        });
        return b ? c(b) : c
    };
    d.get = function (a) {
        var b;
        if (f[a]) b = f[a];
        else if ("object" == typeof document) {
            var c = document.getElementById(a);
            if (c) {
                var d = (c.value || c.innerHTML).replace(/^\s*|\s*$/g, "");
                b = q(d, {
                    filename: a
                })
            }
        }
        return b
    };
    var h = function (a, b) {
            return "string" != typeof a && (b = typeof a, "number" === b ? a += "" : a = "function" === b ? h(a.call(a)) : ""), a
        },
        i = {
            "<": "&#60;",
            ">": "&#62;",
            '"': "&#34;",
            "'": "&#39;",
            "&": "&#38;"
        },
        j = function (a) {
            return i[a]
        },
        k = function (a) {
            return h(a).replace(/&(?![\w#]+;)|[<>"']/g, j)
        },
        l = Array.isArray || function (a) {
            return "[object Array]" === {}.toString.call(a)
        },
        m = function (a, b) {
            var c, d;
            if (l(a))
                for (c = 0, d = a.length; c < d; c++) b.call(a, a[c], c, a);
            else
                for (c in a) b.call(a, a[c], c)
        },
        n = d.utils = {
            $helpers: {},
            $include: g,
            $string: h,
            $escape: k,
            $each: m
        };
    d.helper = function (a, b) {
        o[a] = b
    };
    var o = d.helpers = n.$helpers;
    d.onerror = function (a) {
        var b = "Template Error\n\n";
        for (var c in a) b += "<" + c + ">\n" + a[c] + "\n\n";
        "object" == typeof console && console.error(b)
    };
    var p = function (a) {
            return d.onerror(a),
                function () {
                    return "{Template Error}"
                }
        },
        q = d.compile = function (a, b) {
            function d(c) {
                try {
                    return new i(c, h) + ""
                } catch (d) {
                    return b.debug ? p(d)() : (b.debug = !0, q(a, b)(c))
                }
            }
            b = b || {};
            for (var g in e) void 0 === b[g] && (b[g] = e[g]);
            var h = b.filename;
            try {
                var i = c(a, b)
            } catch (a) {
                return a.filename = h || "anonymous", a.name = "Syntax Error", p(a)
            }
            return d.prototype = i.prototype, d.toString = function () {
                return i.toString()
            }, h && b.cache && (f[h] = d), d
        },
        r = n.$each,
        s = "break,case,catch,continue,debugger,default,delete,do,else,false,finally,for,function,if,in,instanceof,new,null,return,switch,this,throw,true,try,typeof,var,void,while,with,abstract,boolean,byte,char,class,const,double,enum,export,extends,final,float,goto,implements,import,int,interface,long,native,package,private,protected,public,short,static,super,synchronized,throws,transient,volatile,arguments,let,yield,undefined",
        t = /\/\*[\w\W]*?\*\/|\/\/[^\n]*\n|\/\/[^\n]*$|"(?:[^"\\]|\\[\w\W])*"|'(?:[^'\\]|\\[\w\W])*'|\s*\.\s*[$\w\.]+/g,
        u = /[^\w$]+/g,
        v = new RegExp(["\\b" + s.replace(/,/g, "\\b|\\b") + "\\b"].join("|"), "g"),
        w = /^\d[^,]*|,\d[^,]*/g,
        x = /^,+|,+$/g,
        y = /^$|,+/;
    "object" == typeof exports && "undefined" != typeof module ? module.exports = d : "function" == typeof define ? define('template', [], function () {
        return d
    }) : this.template = d
}();
//! moment.js
//! version : 2.15.2
//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
//! license : MIT
//! momentjs.com

;
(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
        typeof define === 'function' && define.amd ? define('moment/moment', factory) :
        global.moment = factory()
}(this, function () {
    'use strict';

    var hookCallback;

    function utils_hooks__hooks() {
        return hookCallback.apply(null, arguments);
    }

    // This is done to register the method called with moment()
    // without creating circular dependencies.
    function setHookCallback(callback) {
        hookCallback = callback;
    }

    function isArray(input) {
        return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';
    }

    function isObject(input) {
        // IE8 will treat undefined and null as object if it wasn't for
        // input != null
        return input != null && Object.prototype.toString.call(input) === '[object Object]';
    }

    function isObjectEmpty(obj) {
        var k;
        for (k in obj) {
            // even if its not own property I'd still call it non-empty
            return false;
        }
        return true;
    }

    function isDate(input) {
        return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';
    }

    function map(arr, fn) {
        var res = [],
            i;
        for (i = 0; i < arr.length; ++i) {
            res.push(fn(arr[i], i));
        }
        return res;
    }

    function hasOwnProp(a, b) {
        return Object.prototype.hasOwnProperty.call(a, b);
    }

    function extend(a, b) {
        for (var i in b) {
            if (hasOwnProp(b, i)) {
                a[i] = b[i];
            }
        }

        if (hasOwnProp(b, 'toString')) {
            a.toString = b.toString;
        }

        if (hasOwnProp(b, 'valueOf')) {
            a.valueOf = b.valueOf;
        }

        return a;
    }

    function create_utc__createUTC(input, format, locale, strict) {
        return createLocalOrUTC(input, format, locale, strict, true).utc();
    }

    function defaultParsingFlags() {
        // We need to deep clone this object.
        return {
            empty: false,
            unusedTokens: [],
            unusedInput: [],
            overflow: -2,
            charsLeftOver: 0,
            nullInput: false,
            invalidMonth: null,
            invalidFormat: false,
            userInvalidated: false,
            iso: false,
            parsedDateParts: [],
            meridiem: null
        };
    }

    function getParsingFlags(m) {
        if (m._pf == null) {
            m._pf = defaultParsingFlags();
        }
        return m._pf;
    }

    var some;
    if (Array.prototype.some) {
        some = Array.prototype.some;
    } else {
        some = function (fun) {
            var t = Object(this);
            var len = t.length >>> 0;

            for (var i = 0; i < len; i++) {
                if (i in t && fun.call(this, t[i], i, t)) {
                    return true;
                }
            }

            return false;
        };
    }

    function valid__isValid(m) {
        if (m._isValid == null) {
            var flags = getParsingFlags(m);
            var parsedParts = some.call(flags.parsedDateParts, function (i) {
                return i != null;
            });
            var isNowValid = !isNaN(m._d.getTime()) &&
                flags.overflow < 0 &&
                !flags.empty &&
                !flags.invalidMonth &&
                !flags.invalidWeekday &&
                !flags.nullInput &&
                !flags.invalidFormat &&
                !flags.userInvalidated &&
                (!flags.meridiem || (flags.meridiem && parsedParts));

            if (m._strict) {
                isNowValid = isNowValid &&
                    flags.charsLeftOver === 0 &&
                    flags.unusedTokens.length === 0 &&
                    flags.bigHour === undefined;
            }

            if (Object.isFrozen == null || !Object.isFrozen(m)) {
                m._isValid = isNowValid;
            } else {
                return isNowValid;
            }
        }
        return m._isValid;
    }

    function valid__createInvalid(flags) {
        var m = create_utc__createUTC(NaN);
        if (flags != null) {
            extend(getParsingFlags(m), flags);
        } else {
            getParsingFlags(m).userInvalidated = true;
        }

        return m;
    }

    function isUndefined(input) {
        return input === void 0;
    }

    // Plugins that add properties should also add the key here (null value),
    // so we can properly clone ourselves.
    var momentProperties = utils_hooks__hooks.momentProperties = [];

    function copyConfig(to, from) {
        var i, prop, val;

        if (!isUndefined(from._isAMomentObject)) {
            to._isAMomentObject = from._isAMomentObject;
        }
        if (!isUndefined(from._i)) {
            to._i = from._i;
        }
        if (!isUndefined(from._f)) {
            to._f = from._f;
        }
        if (!isUndefined(from._l)) {
            to._l = from._l;
        }
        if (!isUndefined(from._strict)) {
            to._strict = from._strict;
        }
        if (!isUndefined(from._tzm)) {
            to._tzm = from._tzm;
        }
        if (!isUndefined(from._isUTC)) {
            to._isUTC = from._isUTC;
        }
        if (!isUndefined(from._offset)) {
            to._offset = from._offset;
        }
        if (!isUndefined(from._pf)) {
            to._pf = getParsingFlags(from);
        }
        if (!isUndefined(from._locale)) {
            to._locale = from._locale;
        }

        if (momentProperties.length > 0) {
            for (i in momentProperties) {
                prop = momentProperties[i];
                val = from[prop];
                if (!isUndefined(val)) {
                    to[prop] = val;
                }
            }
        }

        return to;
    }

    var updateInProgress = false;

    // Moment prototype object
    function Moment(config) {
        copyConfig(this, config);
        this._d = new Date(config._d != null ? config._d.getTime() : NaN);
        // Prevent infinite loop in case updateOffset creates new moment
        // objects.
        if (updateInProgress === false) {
            updateInProgress = true;
            utils_hooks__hooks.updateOffset(this);
            updateInProgress = false;
        }
    }

    function isMoment(obj) {
        return obj instanceof Moment || (obj != null && obj._isAMomentObject != null);
    }

    function absFloor(number) {
        if (number < 0) {
            // -0 -> 0
            return Math.ceil(number) || 0;
        } else {
            return Math.floor(number);
        }
    }

    function toInt(argumentForCoercion) {
        var coercedNumber = +argumentForCoercion,
            value = 0;

        if (coercedNumber !== 0 && isFinite(coercedNumber)) {
            value = absFloor(coercedNumber);
        }

        return value;
    }

    // compare two arrays, return the number of differences
    function compareArrays(array1, array2, dontConvert) {
        var len = Math.min(array1.length, array2.length),
            lengthDiff = Math.abs(array1.length - array2.length),
            diffs = 0,
            i;
        for (i = 0; i < len; i++) {
            if ((dontConvert && array1[i] !== array2[i]) ||
                (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {
                diffs++;
            }
        }
        return diffs + lengthDiff;
    }

    function warn(msg) {
        if (utils_hooks__hooks.suppressDeprecationWarnings === false &&
            (typeof console !== 'undefined') && console.warn) {
            console.warn('Deprecation warning: ' + msg);
        }
    }

    function deprecate(msg, fn) {
        var firstTime = true;

        return extend(function () {
            if (utils_hooks__hooks.deprecationHandler != null) {
                utils_hooks__hooks.deprecationHandler(null, msg);
            }
            if (firstTime) {
                var args = [];
                var arg;
                for (var i = 0; i < arguments.length; i++) {
                    arg = '';
                    if (typeof arguments[i] === 'object') {
                        arg += '\n[' + i + '] ';
                        for (var key in arguments[0]) {
                            arg += key + ': ' + arguments[0][key] + ', ';
                        }
                        arg = arg.slice(0, -2); // Remove trailing comma and space
                    } else {
                        arg = arguments[i];
                    }
                    args.push(arg);
                }
                warn(msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + (new Error()).stack);
                firstTime = false;
            }
            return fn.apply(this, arguments);
        }, fn);
    }

    var deprecations = {};

    function deprecateSimple(name, msg) {
        if (utils_hooks__hooks.deprecationHandler != null) {
            utils_hooks__hooks.deprecationHandler(name, msg);
        }
        if (!deprecations[name]) {
            warn(msg);
            deprecations[name] = true;
        }
    }

    utils_hooks__hooks.suppressDeprecationWarnings = false;
    utils_hooks__hooks.deprecationHandler = null;

    function isFunction(input) {
        return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';
    }

    function locale_set__set(config) {
        var prop, i;
        for (i in config) {
            prop = config[i];
            if (isFunction(prop)) {
                this[i] = prop;
            } else {
                this['_' + i] = prop;
            }
        }
        this._config = config;
        // Lenient ordinal parsing accepts just a number in addition to
        // number + (possibly) stuff coming from _ordinalParseLenient.
        this._ordinalParseLenient = new RegExp(this._ordinalParse.source + '|' + (/\d{1,2}/).source);
    }

    function mergeConfigs(parentConfig, childConfig) {
        var res = extend({}, parentConfig),
            prop;
        for (prop in childConfig) {
            if (hasOwnProp(childConfig, prop)) {
                if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {
                    res[prop] = {};
                    extend(res[prop], parentConfig[prop]);
                    extend(res[prop], childConfig[prop]);
                } else if (childConfig[prop] != null) {
                    res[prop] = childConfig[prop];
                } else {
                    delete res[prop];
                }
            }
        }
        for (prop in parentConfig) {
            if (hasOwnProp(parentConfig, prop) &&
                !hasOwnProp(childConfig, prop) &&
                isObject(parentConfig[prop])) {
                // make sure changes to properties don't modify parent config
                res[prop] = extend({}, res[prop]);
            }
        }
        return res;
    }

    function Locale(config) {
        if (config != null) {
            this.set(config);
        }
    }

    var keys;

    if (Object.keys) {
        keys = Object.keys;
    } else {
        keys = function (obj) {
            var i, res = [];
            for (i in obj) {
                if (hasOwnProp(obj, i)) {
                    res.push(i);
                }
            }
            return res;
        };
    }

    var defaultCalendar = {
        sameDay: '[Today at] LT',
        nextDay: '[Tomorrow at] LT',
        nextWeek: 'dddd [at] LT',
        lastDay: '[Yesterday at] LT',
        lastWeek: '[Last] dddd [at] LT',
        sameElse: 'L'
    };

    function locale_calendar__calendar(key, mom, now) {
        var output = this._calendar[key] || this._calendar['sameElse'];
        return isFunction(output) ? output.call(mom, now) : output;
    }

    var defaultLongDateFormat = {
        LTS: 'h:mm:ss A',
        LT: 'h:mm A',
        L: 'MM/DD/YYYY',
        LL: 'MMMM D, YYYY',
        LLL: 'MMMM D, YYYY h:mm A',
        LLLL: 'dddd, MMMM D, YYYY h:mm A'
    };

    function longDateFormat(key) {
        var format = this._longDateFormat[key],
            formatUpper = this._longDateFormat[key.toUpperCase()];

        if (format || !formatUpper) {
            return format;
        }

        this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {
            return val.slice(1);
        });

        return this._longDateFormat[key];
    }

    var defaultInvalidDate = 'Invalid date';

    function invalidDate() {
        return this._invalidDate;
    }

    var defaultOrdinal = '%d';
    var defaultOrdinalParse = /\d{1,2}/;

    function ordinal(number) {
        return this._ordinal.replace('%d', number);
    }

    var defaultRelativeTime = {
        future: 'in %s',
        past: '%s ago',
        s: 'a few seconds',
        m: 'a minute',
        mm: '%d minutes',
        h: 'an hour',
        hh: '%d hours',
        d: 'a day',
        dd: '%d days',
        M: 'a month',
        MM: '%d months',
        y: 'a year',
        yy: '%d years'
    };

    function relative__relativeTime(number, withoutSuffix, string, isFuture) {
        var output = this._relativeTime[string];
        return (isFunction(output)) ?
            output(number, withoutSuffix, string, isFuture) :
            output.replace(/%d/i, number);
    }

    function pastFuture(diff, output) {
        var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
        return isFunction(format) ? format(output) : format.replace(/%s/i, output);
    }

    var aliases = {};

    function addUnitAlias(unit, shorthand) {
        var lowerCase = unit.toLowerCase();
        aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;
    }

    function normalizeUnits(units) {
        return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;
    }

    function normalizeObjectUnits(inputObject) {
        var normalizedInput = {},
            normalizedProp,
            prop;

        for (prop in inputObject) {
            if (hasOwnProp(inputObject, prop)) {
                normalizedProp = normalizeUnits(prop);
                if (normalizedProp) {
                    normalizedInput[normalizedProp] = inputObject[prop];
                }
            }
        }

        return normalizedInput;
    }

    var priorities = {};

    function addUnitPriority(unit, priority) {
        priorities[unit] = priority;
    }

    function getPrioritizedUnits(unitsObj) {
        var units = [];
        for (var u in unitsObj) {
            units.push({
                unit: u,
                priority: priorities[u]
            });
        }
        units.sort(function (a, b) {
            return a.priority - b.priority;
        });
        return units;
    }

    function makeGetSet(unit, keepTime) {
        return function (value) {
            if (value != null) {
                get_set__set(this, unit, value);
                utils_hooks__hooks.updateOffset(this, keepTime);
                return this;
            } else {
                return get_set__get(this, unit);
            }
        };
    }

    function get_set__get(mom, unit) {
        return mom.isValid() ?
            mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;
    }

    function get_set__set(mom, unit, value) {
        if (mom.isValid()) {
            mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
        }
    }

    // MOMENTS

    function stringGet(units) {
        units = normalizeUnits(units);
        if (isFunction(this[units])) {
            return this[units]();
        }
        return this;
    }


    function stringSet(units, value) {
        if (typeof units === 'object') {
            units = normalizeObjectUnits(units);
            var prioritized = getPrioritizedUnits(units);
            for (var i = 0; i < prioritized.length; i++) {
                this[prioritized[i].unit](units[prioritized[i].unit]);
            }
        } else {
            units = normalizeUnits(units);
            if (isFunction(this[units])) {
                return this[units](value);
            }
        }
        return this;
    }

    function zeroFill(number, targetLength, forceSign) {
        var absNumber = '' + Math.abs(number),
            zerosToFill = targetLength - absNumber.length,
            sign = number >= 0;
        return (sign ? (forceSign ? '+' : '') : '-') +
            Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;
    }

    var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;

    var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g;

    var formatFunctions = {};

    var formatTokenFunctions = {};

    // token:    'M'
    // padded:   ['MM', 2]
    // ordinal:  'Mo'
    // callback: function () { this.month() + 1 }
    function addFormatToken(token, padded, ordinal, callback) {
        var func = callback;
        if (typeof callback === 'string') {
            func = function () {
                return this[callback]();
            };
        }
        if (token) {
            formatTokenFunctions[token] = func;
        }
        if (padded) {
            formatTokenFunctions[padded[0]] = function () {
                return zeroFill(func.apply(this, arguments), padded[1], padded[2]);
            };
        }
        if (ordinal) {
            formatTokenFunctions[ordinal] = function () {
                return this.localeData().ordinal(func.apply(this, arguments), token);
            };
        }
    }

    function removeFormattingTokens(input) {
        if (input.match(/\[[\s\S]/)) {
            return input.replace(/^\[|\]$/g, '');
        }
        return input.replace(/\\/g, '');
    }

    function makeFormatFunction(format) {
        var array = format.match(formattingTokens),
            i, length;

        for (i = 0, length = array.length; i < length; i++) {
            if (formatTokenFunctions[array[i]]) {
                array[i] = formatTokenFunctions[array[i]];
            } else {
                array[i] = removeFormattingTokens(array[i]);
            }
        }

        return function (mom) {
            var output = '',
                i;
            for (i = 0; i < length; i++) {
                output += array[i] instanceof Function ? array[i].call(mom, format) : array[i];
            }
            return output;
        };
    }

    // format date using native date object
    function formatMoment(m, format) {
        if (!m.isValid()) {
            return m.localeData().invalidDate();
        }

        format = expandFormat(format, m.localeData());
        formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);

        return formatFunctions[format](m);
    }

    function expandFormat(format, locale) {
        var i = 5;

        function replaceLongDateFormatTokens(input) {
            return locale.longDateFormat(input) || input;
        }

        localFormattingTokens.lastIndex = 0;
        while (i >= 0 && localFormattingTokens.test(format)) {
            format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
            localFormattingTokens.lastIndex = 0;
            i -= 1;
        }

        return format;
    }

    var match1 = /\d/; //       0 - 9
    var match2 = /\d\d/; //      00 - 99
    var match3 = /\d{3}/; //     000 - 999
    var match4 = /\d{4}/; //    0000 - 9999
    var match6 = /[+-]?\d{6}/; // -999999 - 999999
    var match1to2 = /\d\d?/; //       0 - 99
    var match3to4 = /\d\d\d\d?/; //     999 - 9999
    var match5to6 = /\d\d\d\d\d\d?/; //   99999 - 999999
    var match1to3 = /\d{1,3}/; //       0 - 999
    var match1to4 = /\d{1,4}/; //       0 - 9999
    var match1to6 = /[+-]?\d{1,6}/; // -999999 - 999999

    var matchUnsigned = /\d+/; //       0 - inf
    var matchSigned = /[+-]?\d+/; //    -inf - inf

    var matchOffset = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z
    var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z

    var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123

    // any word (or two) characters or numbers including two/three word month in arabic.
    // includes scottish gaelic two word and hyphenated months
    var matchWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i;


    var regexes = {};

    function addRegexToken(token, regex, strictRegex) {
        regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {
            return (isStrict && strictRegex) ? strictRegex : regex;
        };
    }

    function getParseRegexForToken(token, config) {
        if (!hasOwnProp(regexes, token)) {
            return new RegExp(unescapeFormat(token));
        }

        return regexes[token](config._strict, config._locale);
    }

    // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
    function unescapeFormat(s) {
        return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
            return p1 || p2 || p3 || p4;
        }));
    }

    function regexEscape(s) {
        return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
    }

    var tokens = {};

    function addParseToken(token, callback) {
        var i, func = callback;
        if (typeof token === 'string') {
            token = [token];
        }
        if (typeof callback === 'number') {
            func = function (input, array) {
                array[callback] = toInt(input);
            };
        }
        for (i = 0; i < token.length; i++) {
            tokens[token[i]] = func;
        }
    }

    function addWeekParseToken(token, callback) {
        addParseToken(token, function (input, array, config, token) {
            config._w = config._w || {};
            callback(input, config._w, config, token);
        });
    }

    function addTimeToArrayFromToken(token, input, config) {
        if (input != null && hasOwnProp(tokens, token)) {
            tokens[token](input, config._a, config, token);
        }
    }

    var YEAR = 0;
    var MONTH = 1;
    var DATE = 2;
    var HOUR = 3;
    var MINUTE = 4;
    var SECOND = 5;
    var MILLISECOND = 6;
    var WEEK = 7;
    var WEEKDAY = 8;

    var indexOf;

    if (Array.prototype.indexOf) {
        indexOf = Array.prototype.indexOf;
    } else {
        indexOf = function (o) {
            // I know
            var i;
            for (i = 0; i < this.length; ++i) {
                if (this[i] === o) {
                    return i;
                }
            }
            return -1;
        };
    }

    function daysInMonth(year, month) {
        return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
    }

    // FORMATTING

    addFormatToken('M', ['MM', 2], 'Mo', function () {
        return this.month() + 1;
    });

    addFormatToken('MMM', 0, 0, function (format) {
        return this.localeData().monthsShort(this, format);
    });

    addFormatToken('MMMM', 0, 0, function (format) {
        return this.localeData().months(this, format);
    });

    // ALIASES

    addUnitAlias('month', 'M');

    // PRIORITY

    addUnitPriority('month', 8);

    // PARSING

    addRegexToken('M', match1to2);
    addRegexToken('MM', match1to2, match2);
    addRegexToken('MMM', function (isStrict, locale) {
        return locale.monthsShortRegex(isStrict);
    });
    addRegexToken('MMMM', function (isStrict, locale) {
        return locale.monthsRegex(isStrict);
    });

    addParseToken(['M', 'MM'], function (input, array) {
        array[MONTH] = toInt(input) - 1;
    });

    addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {
        var month = config._locale.monthsParse(input, token, config._strict);
        // if we didn't find a month name, mark the date as invalid.
        if (month != null) {
            array[MONTH] = month;
        } else {
            getParsingFlags(config).invalidMonth = input;
        }
    });

    // LOCALES

    var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/;
    var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');

    function localeMonths(m, format) {
        if (!m) {
            return this._months;
        }
        return isArray(this._months) ? this._months[m.month()] :
            this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()];
    }

    var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');

    function localeMonthsShort(m, format) {
        if (!m) {
            return this._monthsShort;
        }
        return isArray(this._monthsShort) ? this._monthsShort[m.month()] :
            this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];
    }

    function units_month__handleStrictParse(monthName, format, strict) {
        var i, ii, mom, llc = monthName.toLocaleLowerCase();
        if (!this._monthsParse) {
            // this is not used
            this._monthsParse = [];
            this._longMonthsParse = [];
            this._shortMonthsParse = [];
            for (i = 0; i < 12; ++i) {
                mom = create_utc__createUTC([2000, i]);
                this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();
                this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();
            }
        }

        if (strict) {
            if (format === 'MMM') {
                ii = indexOf.call(this._shortMonthsParse, llc);
                return ii !== -1 ? ii : null;
            } else {
                ii = indexOf.call(this._longMonthsParse, llc);
                return ii !== -1 ? ii : null;
            }
        } else {
            if (format === 'MMM') {
                ii = indexOf.call(this._shortMonthsParse, llc);
                if (ii !== -1) {
                    return ii;
                }
                ii = indexOf.call(this._longMonthsParse, llc);
                return ii !== -1 ? ii : null;
            } else {
                ii = indexOf.call(this._longMonthsParse, llc);
                if (ii !== -1) {
                    return ii;
                }
                ii = indexOf.call(this._shortMonthsParse, llc);
                return ii !== -1 ? ii : null;
            }
        }
    }

    function localeMonthsParse(monthName, format, strict) {
        var i, mom, regex;

        if (this._monthsParseExact) {
            return units_month__handleStrictParse.call(this, monthName, format, strict);
        }

        if (!this._monthsParse) {
            this._monthsParse = [];
            this._longMonthsParse = [];
            this._shortMonthsParse = [];
        }

        // TODO: add sorting
        // Sorting makes sure if one month (or abbr) is a prefix of another
        // see sorting in computeMonthsParse
        for (i = 0; i < 12; i++) {
            // make the regex if we don't have it already
            mom = create_utc__createUTC([2000, i]);
            if (strict && !this._longMonthsParse[i]) {
                this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');
                this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');
            }
            if (!strict && !this._monthsParse[i]) {
                regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
                this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
            }
            // test the regex
            if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {
                return i;
            } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {
                return i;
            } else if (!strict && this._monthsParse[i].test(monthName)) {
                return i;
            }
        }
    }

    // MOMENTS

    function setMonth(mom, value) {
        var dayOfMonth;

        if (!mom.isValid()) {
            // No op
            return mom;
        }

        if (typeof value === 'string') {
            if (/^\d+$/.test(value)) {
                value = toInt(value);
            } else {
                value = mom.localeData().monthsParse(value);
                // TODO: Another silent failure?
                if (typeof value !== 'number') {
                    return mom;
                }
            }
        }

        dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));
        mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
        return mom;
    }

    function getSetMonth(value) {
        if (value != null) {
            setMonth(this, value);
            utils_hooks__hooks.updateOffset(this, true);
            return this;
        } else {
            return get_set__get(this, 'Month');
        }
    }

    function getDaysInMonth() {
        return daysInMonth(this.year(), this.month());
    }

    var defaultMonthsShortRegex = matchWord;

    function monthsShortRegex(isStrict) {
        if (this._monthsParseExact) {
            if (!hasOwnProp(this, '_monthsRegex')) {
                computeMonthsParse.call(this);
            }
            if (isStrict) {
                return this._monthsShortStrictRegex;
            } else {
                return this._monthsShortRegex;
            }
        } else {
            if (!hasOwnProp(this, '_monthsShortRegex')) {
                this._monthsShortRegex = defaultMonthsShortRegex;
            }
            return this._monthsShortStrictRegex && isStrict ?
                this._monthsShortStrictRegex : this._monthsShortRegex;
        }
    }

    var defaultMonthsRegex = matchWord;

    function monthsRegex(isStrict) {
        if (this._monthsParseExact) {
            if (!hasOwnProp(this, '_monthsRegex')) {
                computeMonthsParse.call(this);
            }
            if (isStrict) {
                return this._monthsStrictRegex;
            } else {
                return this._monthsRegex;
            }
        } else {
            if (!hasOwnProp(this, '_monthsRegex')) {
                this._monthsRegex = defaultMonthsRegex;
            }
            return this._monthsStrictRegex && isStrict ?
                this._monthsStrictRegex : this._monthsRegex;
        }
    }

    function computeMonthsParse() {
        function cmpLenRev(a, b) {
            return b.length - a.length;
        }

        var shortPieces = [],
            longPieces = [],
            mixedPieces = [],
            i, mom;
        for (i = 0; i < 12; i++) {
            // make the regex if we don't have it already
            mom = create_utc__createUTC([2000, i]);
            shortPieces.push(this.monthsShort(mom, ''));
            longPieces.push(this.months(mom, ''));
            mixedPieces.push(this.months(mom, ''));
            mixedPieces.push(this.monthsShort(mom, ''));
        }
        // Sorting makes sure if one month (or abbr) is a prefix of another it
        // will match the longer piece.
        shortPieces.sort(cmpLenRev);
        longPieces.sort(cmpLenRev);
        mixedPieces.sort(cmpLenRev);
        for (i = 0; i < 12; i++) {
            shortPieces[i] = regexEscape(shortPieces[i]);
            longPieces[i] = regexEscape(longPieces[i]);
        }
        for (i = 0; i < 24; i++) {
            mixedPieces[i] = regexEscape(mixedPieces[i]);
        }

        this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
        this._monthsShortRegex = this._monthsRegex;
        this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
        this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
    }

    // FORMATTING

    addFormatToken('Y', 0, 0, function () {
        var y = this.year();
        return y <= 9999 ? '' + y : '+' + y;
    });

    addFormatToken(0, ['YY', 2], 0, function () {
        return this.year() % 100;
    });

    addFormatToken(0, ['YYYY', 4], 0, 'year');
    addFormatToken(0, ['YYYYY', 5], 0, 'year');
    addFormatToken(0, ['YYYYYY', 6, true], 0, 'year');

    // ALIASES

    addUnitAlias('year', 'y');

    // PRIORITIES

    addUnitPriority('year', 1);

    // PARSING

    addRegexToken('Y', matchSigned);
    addRegexToken('YY', match1to2, match2);
    addRegexToken('YYYY', match1to4, match4);
    addRegexToken('YYYYY', match1to6, match6);
    addRegexToken('YYYYYY', match1to6, match6);

    addParseToken(['YYYYY', 'YYYYYY'], YEAR);
    addParseToken('YYYY', function (input, array) {
        array[YEAR] = input.length === 2 ? utils_hooks__hooks.parseTwoDigitYear(input) : toInt(input);
    });
    addParseToken('YY', function (input, array) {
        array[YEAR] = utils_hooks__hooks.parseTwoDigitYear(input);
    });
    addParseToken('Y', function (input, array) {
        array[YEAR] = parseInt(input, 10);
    });

    // HELPERS

    function daysInYear(year) {
        return isLeapYear(year) ? 366 : 365;
    }

    function isLeapYear(year) {
        return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
    }

    // HOOKS

    utils_hooks__hooks.parseTwoDigitYear = function (input) {
        return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
    };

    // MOMENTS

    var getSetYear = makeGetSet('FullYear', true);

    function getIsLeapYear() {
        return isLeapYear(this.year());
    }

    function createDate(y, m, d, h, M, s, ms) {
        //can't just apply() to create a date:
        //http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply
        var date = new Date(y, m, d, h, M, s, ms);

        //the date constructor remaps years 0-99 to 1900-1999
        if (y < 100 && y >= 0 && isFinite(date.getFullYear())) {
            date.setFullYear(y);
        }
        return date;
    }

    function createUTCDate(y) {
        var date = new Date(Date.UTC.apply(null, arguments));

        //the Date.UTC function remaps years 0-99 to 1900-1999
        if (y < 100 && y >= 0 && isFinite(date.getUTCFullYear())) {
            date.setUTCFullYear(y);
        }
        return date;
    }

    // start-of-first-week - start-of-year
    function firstWeekOffset(year, dow, doy) {
        var // first-week day -- which january is always in the first week (4 for iso, 1 for other)
            fwd = 7 + dow - doy,
            // first-week day local weekday -- which local weekday is fwd
            fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;

        return -fwdlw + fwd - 1;
    }

    //http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
    function dayOfYearFromWeeks(year, week, weekday, dow, doy) {
        var localWeekday = (7 + weekday - dow) % 7,
            weekOffset = firstWeekOffset(year, dow, doy),
            dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,
            resYear, resDayOfYear;

        if (dayOfYear <= 0) {
            resYear = year - 1;
            resDayOfYear = daysInYear(resYear) + dayOfYear;
        } else if (dayOfYear > daysInYear(year)) {
            resYear = year + 1;
            resDayOfYear = dayOfYear - daysInYear(year);
        } else {
            resYear = year;
            resDayOfYear = dayOfYear;
        }

        return {
            year: resYear,
            dayOfYear: resDayOfYear
        };
    }

    function weekOfYear(mom, dow, doy) {
        var weekOffset = firstWeekOffset(mom.year(), dow, doy),
            week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,
            resWeek, resYear;

        if (week < 1) {
            resYear = mom.year() - 1;
            resWeek = week + weeksInYear(resYear, dow, doy);
        } else if (week > weeksInYear(mom.year(), dow, doy)) {
            resWeek = week - weeksInYear(mom.year(), dow, doy);
            resYear = mom.year() + 1;
        } else {
            resYear = mom.year();
            resWeek = week;
        }

        return {
            week: resWeek,
            year: resYear
        };
    }

    function weeksInYear(year, dow, doy) {
        var weekOffset = firstWeekOffset(year, dow, doy),
            weekOffsetNext = firstWeekOffset(year + 1, dow, doy);
        return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
    }

    // FORMATTING

    addFormatToken('w', ['ww', 2], 'wo', 'week');
    addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');

    // ALIASES

    addUnitAlias('week', 'w');
    addUnitAlias('isoWeek', 'W');

    // PRIORITIES

    addUnitPriority('week', 5);
    addUnitPriority('isoWeek', 5);

    // PARSING

    addRegexToken('w', match1to2);
    addRegexToken('ww', match1to2, match2);
    addRegexToken('W', match1to2);
    addRegexToken('WW', match1to2, match2);

    addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {
        week[token.substr(0, 1)] = toInt(input);
    });

    // HELPERS

    // LOCALES

    function localeWeek(mom) {
        return weekOfYear(mom, this._week.dow, this._week.doy).week;
    }

    var defaultLocaleWeek = {
        dow: 0, // Sunday is the first day of the week.
        doy: 6 // The week that contains Jan 1st is the first week of the year.
    };

    function localeFirstDayOfWeek() {
        return this._week.dow;
    }

    function localeFirstDayOfYear() {
        return this._week.doy;
    }

    // MOMENTS

    function getSetWeek(input) {
        var week = this.localeData().week(this);
        return input == null ? week : this.add((input - week) * 7, 'd');
    }

    function getSetISOWeek(input) {
        var week = weekOfYear(this, 1, 4).week;
        return input == null ? week : this.add((input - week) * 7, 'd');
    }

    // FORMATTING

    addFormatToken('d', 0, 'do', 'day');

    addFormatToken('dd', 0, 0, function (format) {
        return this.localeData().weekdaysMin(this, format);
    });

    addFormatToken('ddd', 0, 0, function (format) {
        return this.localeData().weekdaysShort(this, format);
    });

    addFormatToken('dddd', 0, 0, function (format) {
        return this.localeData().weekdays(this, format);
    });

    addFormatToken('e', 0, 0, 'weekday');
    addFormatToken('E', 0, 0, 'isoWeekday');

    // ALIASES

    addUnitAlias('day', 'd');
    addUnitAlias('weekday', 'e');
    addUnitAlias('isoWeekday', 'E');

    // PRIORITY
    addUnitPriority('day', 11);
    addUnitPriority('weekday', 11);
    addUnitPriority('isoWeekday', 11);

    // PARSING

    addRegexToken('d', match1to2);
    addRegexToken('e', match1to2);
    addRegexToken('E', match1to2);
    addRegexToken('dd', function (isStrict, locale) {
        return locale.weekdaysMinRegex(isStrict);
    });
    addRegexToken('ddd', function (isStrict, locale) {
        return locale.weekdaysShortRegex(isStrict);
    });
    addRegexToken('dddd', function (isStrict, locale) {
        return locale.weekdaysRegex(isStrict);
    });

    addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
        var weekday = config._locale.weekdaysParse(input, token, config._strict);
        // if we didn't get a weekday name, mark the date as invalid
        if (weekday != null) {
            week.d = weekday;
        } else {
            getParsingFlags(config).invalidWeekday = input;
        }
    });

    addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {
        week[token] = toInt(input);
    });

    // HELPERS

    function parseWeekday(input, locale) {
        if (typeof input !== 'string') {
            return input;
        }

        if (!isNaN(input)) {
            return parseInt(input, 10);
        }

        input = locale.weekdaysParse(input);
        if (typeof input === 'number') {
            return input;
        }

        return null;
    }

    function parseIsoWeekday(input, locale) {
        if (typeof input === 'string') {
            return locale.weekdaysParse(input) % 7 || 7;
        }
        return isNaN(input) ? null : input;
    }

    // LOCALES

    var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');

    function localeWeekdays(m, format) {
        if (!m) {
            return this._weekdays;
        }
        return isArray(this._weekdays) ? this._weekdays[m.day()] :
            this._weekdays[this._weekdays.isFormat.test(format) ? 'format' : 'standalone'][m.day()];
    }

    var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');

    function localeWeekdaysShort(m) {
        return (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort;
    }

    var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');

    function localeWeekdaysMin(m) {
        return (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin;
    }

    function day_of_week__handleStrictParse(weekdayName, format, strict) {
        var i, ii, mom, llc = weekdayName.toLocaleLowerCase();
        if (!this._weekdaysParse) {
            this._weekdaysParse = [];
            this._shortWeekdaysParse = [];
            this._minWeekdaysParse = [];

            for (i = 0; i < 7; ++i) {
                mom = create_utc__createUTC([2000, 1]).day(i);
                this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();
                this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();
                this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();
            }
        }

        if (strict) {
            if (format === 'dddd') {
                ii = indexOf.call(this._weekdaysParse, llc);
                return ii !== -1 ? ii : null;
            } else if (format === 'ddd') {
                ii = indexOf.call(this._shortWeekdaysParse, llc);
                return ii !== -1 ? ii : null;
            } else {
                ii = indexOf.call(this._minWeekdaysParse, llc);
                return ii !== -1 ? ii : null;
            }
        } else {
            if (format === 'dddd') {
                ii = indexOf.call(this._weekdaysParse, llc);
                if (ii !== -1) {
                    return ii;
                }
                ii = indexOf.call(this._shortWeekdaysParse, llc);
                if (ii !== -1) {
                    return ii;
                }
                ii = indexOf.call(this._minWeekdaysParse, llc);
                return ii !== -1 ? ii : null;
            } else if (format === 'ddd') {
                ii = indexOf.call(this._shortWeekdaysParse, llc);
                if (ii !== -1) {
                    return ii;
                }
                ii = indexOf.call(this._weekdaysParse, llc);
                if (ii !== -1) {
                    return ii;
                }
                ii = indexOf.call(this._minWeekdaysParse, llc);
                return ii !== -1 ? ii : null;
            } else {
                ii = indexOf.call(this._minWeekdaysParse, llc);
                if (ii !== -1) {
                    return ii;
                }
                ii = indexOf.call(this._weekdaysParse, llc);
                if (ii !== -1) {
                    return ii;
                }
                ii = indexOf.call(this._shortWeekdaysParse, llc);
                return ii !== -1 ? ii : null;
            }
        }
    }

    function localeWeekdaysParse(weekdayName, format, strict) {
        var i, mom, regex;

        if (this._weekdaysParseExact) {
            return day_of_week__handleStrictParse.call(this, weekdayName, format, strict);
        }

        if (!this._weekdaysParse) {
            this._weekdaysParse = [];
            this._minWeekdaysParse = [];
            this._shortWeekdaysParse = [];
            this._fullWeekdaysParse = [];
        }

        for (i = 0; i < 7; i++) {
            // make the regex if we don't have it already

            mom = create_utc__createUTC([2000, 1]).day(i);
            if (strict && !this._fullWeekdaysParse[i]) {
                this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\.?') + '$', 'i');
                this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\.?') + '$', 'i');
                this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\.?') + '$', 'i');
            }
            if (!this._weekdaysParse[i]) {
                regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
                this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
            }
            // test the regex
            if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {
                return i;
            } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {
                return i;
            } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {
                return i;
            } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {
                return i;
            }
        }
    }

    // MOMENTS

    function getSetDayOfWeek(input) {
        if (!this.isValid()) {
            return input != null ? this : NaN;
        }
        var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
        if (input != null) {
            input = parseWeekday(input, this.localeData());
            return this.add(input - day, 'd');
        } else {
            return day;
        }
    }

    function getSetLocaleDayOfWeek(input) {
        if (!this.isValid()) {
            return input != null ? this : NaN;
        }
        var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
        return input == null ? weekday : this.add(input - weekday, 'd');
    }

    function getSetISODayOfWeek(input) {
        if (!this.isValid()) {
            return input != null ? this : NaN;
        }

        // behaves the same as moment#day except
        // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
        // as a setter, sunday should belong to the previous week.

        if (input != null) {
            var weekday = parseIsoWeekday(input, this.localeData());
            return this.day(this.day() % 7 ? weekday : weekday - 7);
        } else {
            return this.day() || 7;
        }
    }

    var defaultWeekdaysRegex = matchWord;

    function weekdaysRegex(isStrict) {
        if (this._weekdaysParseExact) {
            if (!hasOwnProp(this, '_weekdaysRegex')) {
                computeWeekdaysParse.call(this);
            }
            if (isStrict) {
                return this._weekdaysStrictRegex;
            } else {
                return this._weekdaysRegex;
            }
        } else {
            if (!hasOwnProp(this, '_weekdaysRegex')) {
                this._weekdaysRegex = defaultWeekdaysRegex;
            }
            return this._weekdaysStrictRegex && isStrict ?
                this._weekdaysStrictRegex : this._weekdaysRegex;
        }
    }

    var defaultWeekdaysShortRegex = matchWord;

    function weekdaysShortRegex(isStrict) {
        if (this._weekdaysParseExact) {
            if (!hasOwnProp(this, '_weekdaysRegex')) {
                computeWeekdaysParse.call(this);
            }
            if (isStrict) {
                return this._weekdaysShortStrictRegex;
            } else {
                return this._weekdaysShortRegex;
            }
        } else {
            if (!hasOwnProp(this, '_weekdaysShortRegex')) {
                this._weekdaysShortRegex = defaultWeekdaysShortRegex;
            }
            return this._weekdaysShortStrictRegex && isStrict ?
                this._weekdaysShortStrictRegex : this._weekdaysShortRegex;
        }
    }

    var defaultWeekdaysMinRegex = matchWord;

    function weekdaysMinRegex(isStrict) {
        if (this._weekdaysParseExact) {
            if (!hasOwnProp(this, '_weekdaysRegex')) {
                computeWeekdaysParse.call(this);
            }
            if (isStrict) {
                return this._weekdaysMinStrictRegex;
            } else {
                return this._weekdaysMinRegex;
            }
        } else {
            if (!hasOwnProp(this, '_weekdaysMinRegex')) {
                this._weekdaysMinRegex = defaultWeekdaysMinRegex;
            }
            return this._weekdaysMinStrictRegex && isStrict ?
                this._weekdaysMinStrictRegex : this._weekdaysMinRegex;
        }
    }


    function computeWeekdaysParse() {
        function cmpLenRev(a, b) {
            return b.length - a.length;
        }

        var minPieces = [],
            shortPieces = [],
            longPieces = [],
            mixedPieces = [],
            i, mom, minp, shortp, longp;
        for (i = 0; i < 7; i++) {
            // make the regex if we don't have it already
            mom = create_utc__createUTC([2000, 1]).day(i);
            minp = this.weekdaysMin(mom, '');
            shortp = this.weekdaysShort(mom, '');
            longp = this.weekdays(mom, '');
            minPieces.push(minp);
            shortPieces.push(shortp);
            longPieces.push(longp);
            mixedPieces.push(minp);
            mixedPieces.push(shortp);
            mixedPieces.push(longp);
        }
        // Sorting makes sure if one weekday (or abbr) is a prefix of another it
        // will match the longer piece.
        minPieces.sort(cmpLenRev);
        shortPieces.sort(cmpLenRev);
        longPieces.sort(cmpLenRev);
        mixedPieces.sort(cmpLenRev);
        for (i = 0; i < 7; i++) {
            shortPieces[i] = regexEscape(shortPieces[i]);
            longPieces[i] = regexEscape(longPieces[i]);
            mixedPieces[i] = regexEscape(mixedPieces[i]);
        }

        this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
        this._weekdaysShortRegex = this._weekdaysRegex;
        this._weekdaysMinRegex = this._weekdaysRegex;

        this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
        this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
        this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');
    }

    // FORMATTING

    function hFormat() {
        return this.hours() % 12 || 12;
    }

    function kFormat() {
        return this.hours() || 24;
    }

    addFormatToken('H', ['HH', 2], 0, 'hour');
    addFormatToken('h', ['hh', 2], 0, hFormat);
    addFormatToken('k', ['kk', 2], 0, kFormat);

    addFormatToken('hmm', 0, 0, function () {
        return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);
    });

    addFormatToken('hmmss', 0, 0, function () {
        return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) +
            zeroFill(this.seconds(), 2);
    });

    addFormatToken('Hmm', 0, 0, function () {
        return '' + this.hours() + zeroFill(this.minutes(), 2);
    });

    addFormatToken('Hmmss', 0, 0, function () {
        return '' + this.hours() + zeroFill(this.minutes(), 2) +
            zeroFill(this.seconds(), 2);
    });

    function meridiem(token, lowercase) {
        addFormatToken(token, 0, 0, function () {
            return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);
        });
    }

    meridiem('a', true);
    meridiem('A', false);

    // ALIASES

    addUnitAlias('hour', 'h');

    // PRIORITY
    addUnitPriority('hour', 13);

    // PARSING

    function matchMeridiem(isStrict, locale) {
        return locale._meridiemParse;
    }

    addRegexToken('a', matchMeridiem);
    addRegexToken('A', matchMeridiem);
    addRegexToken('H', match1to2);
    addRegexToken('h', match1to2);
    addRegexToken('HH', match1to2, match2);
    addRegexToken('hh', match1to2, match2);

    addRegexToken('hmm', match3to4);
    addRegexToken('hmmss', match5to6);
    addRegexToken('Hmm', match3to4);
    addRegexToken('Hmmss', match5to6);

    addParseToken(['H', 'HH'], HOUR);
    addParseToken(['a', 'A'], function (input, array, config) {
        config._isPm = config._locale.isPM(input);
        config._meridiem = input;
    });
    addParseToken(['h', 'hh'], function (input, array, config) {
        array[HOUR] = toInt(input);
        getParsingFlags(config).bigHour = true;
    });
    addParseToken('hmm', function (input, array, config) {
        var pos = input.length - 2;
        array[HOUR] = toInt(input.substr(0, pos));
        array[MINUTE] = toInt(input.substr(pos));
        getParsingFlags(config).bigHour = true;
    });
    addParseToken('hmmss', function (input, array, config) {
        var pos1 = input.length - 4;
        var pos2 = input.length - 2;
        array[HOUR] = toInt(input.substr(0, pos1));
        array[MINUTE] = toInt(input.substr(pos1, 2));
        array[SECOND] = toInt(input.substr(pos2));
        getParsingFlags(config).bigHour = true;
    });
    addParseToken('Hmm', function (input, array, config) {
        var pos = input.length - 2;
        array[HOUR] = toInt(input.substr(0, pos));
        array[MINUTE] = toInt(input.substr(pos));
    });
    addParseToken('Hmmss', function (input, array, config) {
        var pos1 = input.length - 4;
        var pos2 = input.length - 2;
        array[HOUR] = toInt(input.substr(0, pos1));
        array[MINUTE] = toInt(input.substr(pos1, 2));
        array[SECOND] = toInt(input.substr(pos2));
    });

    // LOCALES

    function localeIsPM(input) {
        // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
        // Using charAt should be more compatible.
        return ((input + '').toLowerCase().charAt(0) === 'p');
    }

    var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i;

    function localeMeridiem(hours, minutes, isLower) {
        if (hours > 11) {
            return isLower ? 'pm' : 'PM';
        } else {
            return isLower ? 'am' : 'AM';
        }
    }


    // MOMENTS

    // Setting the hour should keep the time, because the user explicitly
    // specified which hour he wants. So trying to maintain the same hour (in
    // a new timezone) makes sense. Adding/subtracting hours does not follow
    // this rule.
    var getSetHour = makeGetSet('Hours', true);

    var baseConfig = {
        calendar: defaultCalendar,
        longDateFormat: defaultLongDateFormat,
        invalidDate: defaultInvalidDate,
        ordinal: defaultOrdinal,
        ordinalParse: defaultOrdinalParse,
        relativeTime: defaultRelativeTime,

        months: defaultLocaleMonths,
        monthsShort: defaultLocaleMonthsShort,

        week: defaultLocaleWeek,

        weekdays: defaultLocaleWeekdays,
        weekdaysMin: defaultLocaleWeekdaysMin,
        weekdaysShort: defaultLocaleWeekdaysShort,

        meridiemParse: defaultLocaleMeridiemParse
    };

    // internal storage for locale config files
    var locales = {};
    var globalLocale;

    function normalizeLocale(key) {
        return key ? key.toLowerCase().replace('_', '-') : key;
    }

    // pick the locale from the array
    // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
    // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
    function chooseLocale(names) {
        var i = 0,
            j, next, locale, split;

        while (i < names.length) {
            split = normalizeLocale(names[i]).split('-');
            j = split.length;
            next = normalizeLocale(names[i + 1]);
            next = next ? next.split('-') : null;
            while (j > 0) {
                locale = loadLocale(split.slice(0, j).join('-'));
                if (locale) {
                    return locale;
                }
                if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
                    //the next array item is better than a shallower substring of this one
                    break;
                }
                j--;
            }
            i++;
        }
        return null;
    }

    function loadLocale(name) {
        var oldLocale = null;
        // TODO: Find a better way to register and load all the locales in Node
        if (!locales[name] && (typeof module !== 'undefined') &&
            module && module.exports) {
            try {
                oldLocale = globalLocale._abbr;
                require('./locale/' + name);
                // because defineLocale currently also sets the global locale, we
                // want to undo that for lazy loaded locales
                locale_locales__getSetGlobalLocale(oldLocale);
            } catch (e) {}
        }
        return locales[name];
    }

    // This function will load locale and then set the global locale.  If
    // no arguments are passed in, it will simply return the current global
    // locale key.
    function locale_locales__getSetGlobalLocale(key, values) {
        var data;
        if (key) {
            if (isUndefined(values)) {
                data = locale_locales__getLocale(key);
            } else {
                data = defineLocale(key, values);
            }

            if (data) {
                // moment.duration._locale = moment._locale = data;
                globalLocale = data;
            }
        }

        return globalLocale._abbr;
    }

    function defineLocale(name, config) {
        if (config !== null) {
            var parentConfig = baseConfig;
            config.abbr = name;
            if (locales[name] != null) {
                deprecateSimple('defineLocaleOverride',
                    'use moment.updateLocale(localeName, config) to change ' +
                    'an existing locale. moment.defineLocale(localeName, ' +
                    'config) should only be used for creating a new locale ' +
                    'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.');
                parentConfig = locales[name]._config;
            } else if (config.parentLocale != null) {
                if (locales[config.parentLocale] != null) {
                    parentConfig = locales[config.parentLocale]._config;
                } else {
                    // treat as if there is no base config
                    deprecateSimple('parentLocaleUndefined',
                        'specified parentLocale is not defined yet. See http://momentjs.com/guides/#/warnings/parent-locale/');
                }
            }
            locales[name] = new Locale(mergeConfigs(parentConfig, config));

            // backwards compat for now: also set the locale
            locale_locales__getSetGlobalLocale(name);

            return locales[name];
        } else {
            // useful for testing
            delete locales[name];
            return null;
        }
    }

    function updateLocale(name, config) {
        if (config != null) {
            var locale, parentConfig = baseConfig;
            // MERGE
            if (locales[name] != null) {
                parentConfig = locales[name]._config;
            }
            config = mergeConfigs(parentConfig, config);
            locale = new Locale(config);
            locale.parentLocale = locales[name];
            locales[name] = locale;

            // backwards compat for now: also set the locale
            locale_locales__getSetGlobalLocale(name);
        } else {
            // pass null for config to unupdate, useful for tests
            if (locales[name] != null) {
                if (locales[name].parentLocale != null) {
                    locales[name] = locales[name].parentLocale;
                } else if (locales[name] != null) {
                    delete locales[name];
                }
            }
        }
        return locales[name];
    }

    // returns locale data
    function locale_locales__getLocale(key) {
        var locale;

        if (key && key._locale && key._locale._abbr) {
            key = key._locale._abbr;
        }

        if (!key) {
            return globalLocale;
        }

        if (!isArray(key)) {
            //short-circuit everything else
            locale = loadLocale(key);
            if (locale) {
                return locale;
            }
            key = [key];
        }

        return chooseLocale(key);
    }

    function locale_locales__listLocales() {
        return keys(locales);
    }

    function checkOverflow(m) {
        var overflow;
        var a = m._a;

        if (a && getParsingFlags(m).overflow === -2) {
            overflow =
                a[MONTH] < 0 || a[MONTH] > 11 ? MONTH :
                a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH]) ? DATE :
                a[HOUR] < 0 || a[HOUR] > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR :
                a[MINUTE] < 0 || a[MINUTE] > 59 ? MINUTE :
                a[SECOND] < 0 || a[SECOND] > 59 ? SECOND :
                a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND :
                -1;

            if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
                overflow = DATE;
            }
            if (getParsingFlags(m)._overflowWeeks && overflow === -1) {
                overflow = WEEK;
            }
            if (getParsingFlags(m)._overflowWeekday && overflow === -1) {
                overflow = WEEKDAY;
            }

            getParsingFlags(m).overflow = overflow;
        }

        return m;
    }

    // iso 8601 regex
    // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)
    var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?/;
    var basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?/;

    var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/;

    var isoDates = [
        ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/],
        ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/],
        ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/],
        ['GGGG-[W]WW', /\d{4}-W\d\d/, false],
        ['YYYY-DDD', /\d{4}-\d{3}/],
        ['YYYY-MM', /\d{4}-\d\d/, false],
        ['YYYYYYMMDD', /[+-]\d{10}/],
        ['YYYYMMDD', /\d{8}/],
        // YYYYMM is NOT allowed by the standard
        ['GGGG[W]WWE', /\d{4}W\d{3}/],
        ['GGGG[W]WW', /\d{4}W\d{2}/, false],
        ['YYYYDDD', /\d{7}/]
    ];

    // iso time formats and regexes
    var isoTimes = [
        ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/],
        ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/],
        ['HH:mm:ss', /\d\d:\d\d:\d\d/],
        ['HH:mm', /\d\d:\d\d/],
        ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/],
        ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/],
        ['HHmmss', /\d\d\d\d\d\d/],
        ['HHmm', /\d\d\d\d/],
        ['HH', /\d\d/]
    ];

    var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i;

    // date from iso format
    function configFromISO(config) {
        var i, l,
            string = config._i,
            match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),
            allowTime, dateFormat, timeFormat, tzFormat;

        if (match) {
            getParsingFlags(config).iso = true;

            for (i = 0, l = isoDates.length; i < l; i++) {
                if (isoDates[i][1].exec(match[1])) {
                    dateFormat = isoDates[i][0];
                    allowTime = isoDates[i][2] !== false;
                    break;
                }
            }
            if (dateFormat == null) {
                config._isValid = false;
                return;
            }
            if (match[3]) {
                for (i = 0, l = isoTimes.length; i < l; i++) {
                    if (isoTimes[i][1].exec(match[3])) {
                        // match[2] should be 'T' or space
                        timeFormat = (match[2] || ' ') + isoTimes[i][0];
                        break;
                    }
                }
                if (timeFormat == null) {
                    config._isValid = false;
                    return;
                }
            }
            if (!allowTime && timeFormat != null) {
                config._isValid = false;
                return;
            }
            if (match[4]) {
                if (tzRegex.exec(match[4])) {
                    tzFormat = 'Z';
                } else {
                    config._isValid = false;
                    return;
                }
            }
            config._f = dateFormat + (timeFormat || '') + (tzFormat || '');
            configFromStringAndFormat(config);
        } else {
            config._isValid = false;
        }
    }

    // date from iso format or fallback
    function configFromString(config) {
        var matched = aspNetJsonRegex.exec(config._i);

        if (matched !== null) {
            config._d = new Date(+matched[1]);
            return;
        }

        configFromISO(config);
        if (config._isValid === false) {
            delete config._isValid;
            utils_hooks__hooks.createFromInputFallback(config);
        }
    }

    utils_hooks__hooks.createFromInputFallback = deprecate(
        'value provided is not in a recognized ISO format. moment construction falls back to js Date(), ' +
        'which is not reliable across all browsers and versions. Non ISO date formats are ' +
        'discouraged and will be removed in an upcoming major release. Please refer to ' +
        'http://momentjs.com/guides/#/warnings/js-date/ for more info.',
        function (config) {
            config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
        }
    );

    // Pick the first defined of two or three arguments.
    function defaults(a, b, c) {
        if (a != null) {
            return a;
        }
        if (b != null) {
            return b;
        }
        return c;
    }

    function currentDateArray(config) {
        // hooks is actually the exported moment object
        var nowValue = new Date(utils_hooks__hooks.now());
        if (config._useUTC) {
            return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];
        }
        return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];
    }

    // convert an array to a date.
    // the array should mirror the parameters below
    // note: all values past the year are optional and will default to the lowest possible value.
    // [year, month, day , hour, minute, second, millisecond]
    function configFromArray(config) {
        var i, date, input = [],
            currentDate, yearToUse;

        if (config._d) {
            return;
        }

        currentDate = currentDateArray(config);

        //compute day of the year from weeks and weekdays
        if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
            dayOfYearFromWeekInfo(config);
        }

        //if the day of the year is set, figure out what it is
        if (config._dayOfYear) {
            yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);

            if (config._dayOfYear > daysInYear(yearToUse)) {
                getParsingFlags(config)._overflowDayOfYear = true;
            }

            date = createUTCDate(yearToUse, 0, config._dayOfYear);
            config._a[MONTH] = date.getUTCMonth();
            config._a[DATE] = date.getUTCDate();
        }

        // Default to current date.
        // * if no year, month, day of month are given, default to today
        // * if day of month is given, default month and year
        // * if month is given, default only year
        // * if year is given, don't default anything
        for (i = 0; i < 3 && config._a[i] == null; ++i) {
            config._a[i] = input[i] = currentDate[i];
        }

        // Zero out whatever was not defaulted, including time
        for (; i < 7; i++) {
            config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];
        }

        // Check for 24:00:00.000
        if (config._a[HOUR] === 24 &&
            config._a[MINUTE] === 0 &&
            config._a[SECOND] === 0 &&
            config._a[MILLISECOND] === 0) {
            config._nextDay = true;
            config._a[HOUR] = 0;
        }

        config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);
        // Apply timezone offset from input. The actual utcOffset can be changed
        // with parseZone.
        if (config._tzm != null) {
            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
        }

        if (config._nextDay) {
            config._a[HOUR] = 24;
        }
    }

    function dayOfYearFromWeekInfo(config) {
        var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;

        w = config._w;
        if (w.GG != null || w.W != null || w.E != null) {
            dow = 1;
            doy = 4;

            // TODO: We need to take the current isoWeekYear, but that depends on
            // how we interpret now (local, utc, fixed offset). So create
            // a now version of current config (take local/utc/offset flags, and
            // create now).
            weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(local__createLocal(), 1, 4).year);
            week = defaults(w.W, 1);
            weekday = defaults(w.E, 1);
            if (weekday < 1 || weekday > 7) {
                weekdayOverflow = true;
            }
        } else {
            dow = config._locale._week.dow;
            doy = config._locale._week.doy;

            weekYear = defaults(w.gg, config._a[YEAR], weekOfYear(local__createLocal(), dow, doy).year);
            week = defaults(w.w, 1);

            if (w.d != null) {
                // weekday -- low day numbers are considered next week
                weekday = w.d;
                if (weekday < 0 || weekday > 6) {
                    weekdayOverflow = true;
                }
            } else if (w.e != null) {
                // local weekday -- counting starts from begining of week
                weekday = w.e + dow;
                if (w.e < 0 || w.e > 6) {
                    weekdayOverflow = true;
                }
            } else {
                // default to begining of week
                weekday = dow;
            }
        }
        if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {
            getParsingFlags(config)._overflowWeeks = true;
        } else if (weekdayOverflow != null) {
            getParsingFlags(config)._overflowWeekday = true;
        } else {
            temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);
            config._a[YEAR] = temp.year;
            config._dayOfYear = temp.dayOfYear;
        }
    }

    // constant that refers to the ISO standard
    utils_hooks__hooks.ISO_8601 = function () {};

    // date from string and format string
    function configFromStringAndFormat(config) {
        // TODO: Move this to another part of the creation flow to prevent circular deps
        if (config._f === utils_hooks__hooks.ISO_8601) {
            configFromISO(config);
            return;
        }

        config._a = [];
        getParsingFlags(config).empty = true;

        // This array is used to make a Date, either with `new Date` or `Date.UTC`
        var string = '' + config._i,
            i, parsedInput, tokens, token, skipped,
            stringLength = string.length,
            totalParsedInputLength = 0;

        tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];

        for (i = 0; i < tokens.length; i++) {
            token = tokens[i];
            parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];
            // console.log('token', token, 'parsedInput', parsedInput,
            //         'regex', getParseRegexForToken(token, config));
            if (parsedInput) {
                skipped = string.substr(0, string.indexOf(parsedInput));
                if (skipped.length > 0) {
                    getParsingFlags(config).unusedInput.push(skipped);
                }
                string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
                totalParsedInputLength += parsedInput.length;
            }
            // don't parse if it's not a known token
            if (formatTokenFunctions[token]) {
                if (parsedInput) {
                    getParsingFlags(config).empty = false;
                } else {
                    getParsingFlags(config).unusedTokens.push(token);
                }
                addTimeToArrayFromToken(token, parsedInput, config);
            } else if (config._strict && !parsedInput) {
                getParsingFlags(config).unusedTokens.push(token);
            }
        }

        // add remaining unparsed input length to the string
        getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;
        if (string.length > 0) {
            getParsingFlags(config).unusedInput.push(string);
        }

        // clear _12h flag if hour is <= 12
        if (config._a[HOUR] <= 12 &&
            getParsingFlags(config).bigHour === true &&
            config._a[HOUR] > 0) {
            getParsingFlags(config).bigHour = undefined;
        }

        getParsingFlags(config).parsedDateParts = config._a.slice(0);
        getParsingFlags(config).meridiem = config._meridiem;
        // handle meridiem
        config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);

        configFromArray(config);
        checkOverflow(config);
    }


    function meridiemFixWrap(locale, hour, meridiem) {
        var isPm;

        if (meridiem == null) {
            // nothing to do
            return hour;
        }
        if (locale.meridiemHour != null) {
            return locale.meridiemHour(hour, meridiem);
        } else if (locale.isPM != null) {
            // Fallback
            isPm = locale.isPM(meridiem);
            if (isPm && hour < 12) {
                hour += 12;
            }
            if (!isPm && hour === 12) {
                hour = 0;
            }
            return hour;
        } else {
            // this is not supposed to happen
            return hour;
        }
    }

    // date from string and array of format strings
    function configFromStringAndArray(config) {
        var tempConfig,
            bestMoment,

            scoreToBeat,
            i,
            currentScore;

        if (config._f.length === 0) {
            getParsingFlags(config).invalidFormat = true;
            config._d = new Date(NaN);
            return;
        }

        for (i = 0; i < config._f.length; i++) {
            currentScore = 0;
            tempConfig = copyConfig({}, config);
            if (config._useUTC != null) {
                tempConfig._useUTC = config._useUTC;
            }
            tempConfig._f = config._f[i];
            configFromStringAndFormat(tempConfig);

            if (!valid__isValid(tempConfig)) {
                continue;
            }

            // if there is any input that was not parsed add a penalty for that format
            currentScore += getParsingFlags(tempConfig).charsLeftOver;

            //or tokens
            currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;

            getParsingFlags(tempConfig).score = currentScore;

            if (scoreToBeat == null || currentScore < scoreToBeat) {
                scoreToBeat = currentScore;
                bestMoment = tempConfig;
            }
        }

        extend(config, bestMoment || tempConfig);
    }

    function configFromObject(config) {
        if (config._d) {
            return;
        }

        var i = normalizeObjectUnits(config._i);
        config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {
            return obj && parseInt(obj, 10);
        });

        configFromArray(config);
    }

    function createFromConfig(config) {
        var res = new Moment(checkOverflow(prepareConfig(config)));
        if (res._nextDay) {
            // Adding is smart enough around DST
            res.add(1, 'd');
            res._nextDay = undefined;
        }

        return res;
    }

    function prepareConfig(config) {
        var input = config._i,
            format = config._f;

        config._locale = config._locale || locale_locales__getLocale(config._l);

        if (input === null || (format === undefined && input === '')) {
            return valid__createInvalid({
                nullInput: true
            });
        }

        if (typeof input === 'string') {
            config._i = input = config._locale.preparse(input);
        }

        if (isMoment(input)) {
            return new Moment(checkOverflow(input));
        } else if (isArray(format)) {
            configFromStringAndArray(config);
        } else if (isDate(input)) {
            config._d = input;
        } else if (format) {
            configFromStringAndFormat(config);
        } else {
            configFromInput(config);
        }

        if (!valid__isValid(config)) {
            config._d = null;
        }

        return config;
    }

    function configFromInput(config) {
        var input = config._i;
        if (input === undefined) {
            config._d = new Date(utils_hooks__hooks.now());
        } else if (isDate(input)) {
            config._d = new Date(input.valueOf());
        } else if (typeof input === 'string') {
            configFromString(config);
        } else if (isArray(input)) {
            config._a = map(input.slice(0), function (obj) {
                return parseInt(obj, 10);
            });
            configFromArray(config);
        } else if (typeof (input) === 'object') {
            configFromObject(config);
        } else if (typeof (input) === 'number') {
            // from milliseconds
            config._d = new Date(input);
        } else {
            utils_hooks__hooks.createFromInputFallback(config);
        }
    }

    function createLocalOrUTC(input, format, locale, strict, isUTC) {
        var c = {};

        if (typeof (locale) === 'boolean') {
            strict = locale;
            locale = undefined;
        }

        if ((isObject(input) && isObjectEmpty(input)) ||
            (isArray(input) && input.length === 0)) {
            input = undefined;
        }
        // object construction must be done this way.
        // https://github.com/moment/moment/issues/1423
        c._isAMomentObject = true;
        c._useUTC = c._isUTC = isUTC;
        c._l = locale;
        c._i = input;
        c._f = format;
        c._strict = strict;

        return createFromConfig(c);
    }

    function local__createLocal(input, format, locale, strict) {
        return createLocalOrUTC(input, format, locale, strict, false);
    }

    var prototypeMin = deprecate(
        'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/',
        function () {
            var other = local__createLocal.apply(null, arguments);
            if (this.isValid() && other.isValid()) {
                return other < this ? this : other;
            } else {
                return valid__createInvalid();
            }
        }
    );

    var prototypeMax = deprecate(
        'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/',
        function () {
            var other = local__createLocal.apply(null, arguments);
            if (this.isValid() && other.isValid()) {
                return other > this ? this : other;
            } else {
                return valid__createInvalid();
            }
        }
    );

    // Pick a moment m from moments so that m[fn](other) is true for all
    // other. This relies on the function fn to be transitive.
    //
    // moments should either be an array of moment objects or an array, whose
    // first element is an array of moment objects.
    function pickBy(fn, moments) {
        var res, i;
        if (moments.length === 1 && isArray(moments[0])) {
            moments = moments[0];
        }
        if (!moments.length) {
            return local__createLocal();
        }
        res = moments[0];
        for (i = 1; i < moments.length; ++i) {
            if (!moments[i].isValid() || moments[i][fn](res)) {
                res = moments[i];
            }
        }
        return res;
    }

    // TODO: Use [].sort instead?
    function min() {
        var args = [].slice.call(arguments, 0);

        return pickBy('isBefore', args);
    }

    function max() {
        var args = [].slice.call(arguments, 0);

        return pickBy('isAfter', args);
    }

    var now = function () {
        return Date.now ? Date.now() : +(new Date());
    };

    function Duration(duration) {
        var normalizedInput = normalizeObjectUnits(duration),
            years = normalizedInput.year || 0,
            quarters = normalizedInput.quarter || 0,
            months = normalizedInput.month || 0,
            weeks = normalizedInput.week || 0,
            days = normalizedInput.day || 0,
            hours = normalizedInput.hour || 0,
            minutes = normalizedInput.minute || 0,
            seconds = normalizedInput.second || 0,
            milliseconds = normalizedInput.millisecond || 0;

        // representation for dateAddRemove
        this._milliseconds = +milliseconds +
            seconds * 1e3 + // 1000
            minutes * 6e4 + // 1000 * 60
            hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
        // Because of dateAddRemove treats 24 hours as different from a
        // day when working around DST, we need to store them separately
        this._days = +days +
            weeks * 7;
        // It is impossible translate months into days without knowing
        // which months you are are talking about, so we have to store
        // it separately.
        this._months = +months +
            quarters * 3 +
            years * 12;

        this._data = {};

        this._locale = locale_locales__getLocale();

        this._bubble();
    }

    function isDuration(obj) {
        return obj instanceof Duration;
    }

    function absRound(number) {
        if (number < 0) {
            return Math.round(-1 * number) * -1;
        } else {
            return Math.round(number);
        }
    }

    // FORMATTING

    function offset(token, separator) {
        addFormatToken(token, 0, 0, function () {
            var offset = this.utcOffset();
            var sign = '+';
            if (offset < 0) {
                offset = -offset;
                sign = '-';
            }
            return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2);
        });
    }

    offset('Z', ':');
    offset('ZZ', '');

    // PARSING

    addRegexToken('Z', matchShortOffset);
    addRegexToken('ZZ', matchShortOffset);
    addParseToken(['Z', 'ZZ'], function (input, array, config) {
        config._useUTC = true;
        config._tzm = offsetFromString(matchShortOffset, input);
    });

    // HELPERS

    // timezone chunker
    // '+10:00' > ['10',  '00']
    // '-1530'  > ['-15', '30']
    var chunkOffset = /([\+\-]|\d\d)/gi;

    function offsetFromString(matcher, string) {
        var matches = ((string || '').match(matcher) || []);
        var chunk = matches[matches.length - 1] || [];
        var parts = (chunk + '').match(chunkOffset) || ['-', 0, 0];
        var minutes = +(parts[1] * 60) + toInt(parts[2]);

        return parts[0] === '+' ? minutes : -minutes;
    }

    // Return a moment from input, that is local/utc/zone equivalent to model.
    function cloneWithOffset(input, model) {
        var res, diff;
        if (model._isUTC) {
            res = model.clone();
            diff = (isMoment(input) || isDate(input) ? input.valueOf() : local__createLocal(input).valueOf()) - res.valueOf();
            // Use low-level api, because this fn is low-level api.
            res._d.setTime(res._d.valueOf() + diff);
            utils_hooks__hooks.updateOffset(res, false);
            return res;
        } else {
            return local__createLocal(input).local();
        }
    }

    function getDateOffset(m) {
        // On Firefox.24 Date#getTimezoneOffset returns a floating point.
        // https://github.com/moment/moment/pull/1871
        return -Math.round(m._d.getTimezoneOffset() / 15) * 15;
    }

    // HOOKS

    // This function will be called whenever a moment is mutated.
    // It is intended to keep the offset in sync with the timezone.
    utils_hooks__hooks.updateOffset = function () {};

    // MOMENTS

    // keepLocalTime = true means only change the timezone, without
    // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
    // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
    // +0200, so we adjust the time as needed, to be valid.
    //
    // Keeping the time actually adds/subtracts (one hour)
    // from the actual represented time. That is why we call updateOffset
    // a second time. In case it wants us to change the offset again
    // _changeInProgress == true case, then we have to adjust, because
    // there is no such time in the given timezone.
    function getSetOffset(input, keepLocalTime) {
        var offset = this._offset || 0,
            localAdjust;
        if (!this.isValid()) {
            return input != null ? this : NaN;
        }
        if (input != null) {
            if (typeof input === 'string') {
                input = offsetFromString(matchShortOffset, input);
            } else if (Math.abs(input) < 16) {
                input = input * 60;
            }
            if (!this._isUTC && keepLocalTime) {
                localAdjust = getDateOffset(this);
            }
            this._offset = input;
            this._isUTC = true;
            if (localAdjust != null) {
                this.add(localAdjust, 'm');
            }
            if (offset !== input) {
                if (!keepLocalTime || this._changeInProgress) {
                    add_subtract__addSubtract(this, create__createDuration(input - offset, 'm'), 1, false);
                } else if (!this._changeInProgress) {
                    this._changeInProgress = true;
                    utils_hooks__hooks.updateOffset(this, true);
                    this._changeInProgress = null;
                }
            }
            return this;
        } else {
            return this._isUTC ? offset : getDateOffset(this);
        }
    }

    function getSetZone(input, keepLocalTime) {
        if (input != null) {
            if (typeof input !== 'string') {
                input = -input;
            }

            this.utcOffset(input, keepLocalTime);

            return this;
        } else {
            return -this.utcOffset();
        }
    }

    function setOffsetToUTC(keepLocalTime) {
        return this.utcOffset(0, keepLocalTime);
    }

    function setOffsetToLocal(keepLocalTime) {
        if (this._isUTC) {
            this.utcOffset(0, keepLocalTime);
            this._isUTC = false;

            if (keepLocalTime) {
                this.subtract(getDateOffset(this), 'm');
            }
        }
        return this;
    }

    function setOffsetToParsedOffset() {
        if (this._tzm) {
            this.utcOffset(this._tzm);
        } else if (typeof this._i === 'string') {
            var tZone = offsetFromString(matchOffset, this._i);

            if (tZone === 0) {
                this.utcOffset(0, true);
            } else {
                this.utcOffset(offsetFromString(matchOffset, this._i));
            }
        }
        return this;
    }

    function hasAlignedHourOffset(input) {
        if (!this.isValid()) {
            return false;
        }
        input = input ? local__createLocal(input).utcOffset() : 0;

        return (this.utcOffset() - input) % 60 === 0;
    }

    function isDaylightSavingTime() {
        return (
            this.utcOffset() > this.clone().month(0).utcOffset() ||
            this.utcOffset() > this.clone().month(5).utcOffset()
        );
    }

    function isDaylightSavingTimeShifted() {
        if (!isUndefined(this._isDSTShifted)) {
            return this._isDSTShifted;
        }

        var c = {};

        copyConfig(c, this);
        c = prepareConfig(c);

        if (c._a) {
            var other = c._isUTC ? create_utc__createUTC(c._a) : local__createLocal(c._a);
            this._isDSTShifted = this.isValid() &&
                compareArrays(c._a, other.toArray()) > 0;
        } else {
            this._isDSTShifted = false;
        }

        return this._isDSTShifted;
    }

    function isLocal() {
        return this.isValid() ? !this._isUTC : false;
    }

    function isUtcOffset() {
        return this.isValid() ? this._isUTC : false;
    }

    function isUtc() {
        return this.isValid() ? this._isUTC && this._offset === 0 : false;
    }

    // ASP.NET json date format regex
    var aspNetRegex = /^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/;

    // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
    // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
    // and further modified to allow for strings containing both week and day
    var isoRegex = /^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;

    function create__createDuration(input, key) {
        var duration = input,
            // matching against regexp is expensive, do it on demand
            match = null,
            sign,
            ret,
            diffRes;

        if (isDuration(input)) {
            duration = {
                ms: input._milliseconds,
                d: input._days,
                M: input._months
            };
        } else if (typeof input === 'number') {
            duration = {};
            if (key) {
                duration[key] = input;
            } else {
                duration.milliseconds = input;
            }
        } else if (!!(match = aspNetRegex.exec(input))) {
            sign = (match[1] === '-') ? -1 : 1;
            duration = {
                y: 0,
                d: toInt(match[DATE]) * sign,
                h: toInt(match[HOUR]) * sign,
                m: toInt(match[MINUTE]) * sign,
                s: toInt(match[SECOND]) * sign,
                ms: toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match
            };
        } else if (!!(match = isoRegex.exec(input))) {
            sign = (match[1] === '-') ? -1 : 1;
            duration = {
                y: parseIso(match[2], sign),
                M: parseIso(match[3], sign),
                w: parseIso(match[4], sign),
                d: parseIso(match[5], sign),
                h: parseIso(match[6], sign),
                m: parseIso(match[7], sign),
                s: parseIso(match[8], sign)
            };
        } else if (duration == null) { // checks for null or undefined
            duration = {};
        } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {
            diffRes = momentsDifference(local__createLocal(duration.from), local__createLocal(duration.to));

            duration = {};
            duration.ms = diffRes.milliseconds;
            duration.M = diffRes.months;
        }

        ret = new Duration(duration);

        if (isDuration(input) && hasOwnProp(input, '_locale')) {
            ret._locale = input._locale;
        }

        return ret;
    }

    create__createDuration.fn = Duration.prototype;

    function parseIso(inp, sign) {
        // We'd normally use ~~inp for this, but unfortunately it also
        // converts floats to ints.
        // inp may be undefined, so careful calling replace on it.
        var res = inp && parseFloat(inp.replace(',', '.'));
        // apply sign while we're at it
        return (isNaN(res) ? 0 : res) * sign;
    }

    function positiveMomentsDifference(base, other) {
        var res = {
            milliseconds: 0,
            months: 0
        };

        res.months = other.month() - base.month() +
            (other.year() - base.year()) * 12;
        if (base.clone().add(res.months, 'M').isAfter(other)) {
            --res.months;
        }

        res.milliseconds = +other - +(base.clone().add(res.months, 'M'));

        return res;
    }

    function momentsDifference(base, other) {
        var res;
        if (!(base.isValid() && other.isValid())) {
            return {
                milliseconds: 0,
                months: 0
            };
        }

        other = cloneWithOffset(other, base);
        if (base.isBefore(other)) {
            res = positiveMomentsDifference(base, other);
        } else {
            res = positiveMomentsDifference(other, base);
            res.milliseconds = -res.milliseconds;
            res.months = -res.months;
        }

        return res;
    }

    // TODO: remove 'name' arg after deprecation is removed
    function createAdder(direction, name) {
        return function (val, period) {
            var dur, tmp;
            //invert the arguments, but complain about it
            if (period !== null && !isNaN(+period)) {
                deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' +
                    'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.');
                tmp = val;
                val = period;
                period = tmp;
            }

            val = typeof val === 'string' ? +val : val;
            dur = create__createDuration(val, period);
            add_subtract__addSubtract(this, dur, direction);
            return this;
        };
    }

    function add_subtract__addSubtract(mom, duration, isAdding, updateOffset) {
        var milliseconds = duration._milliseconds,
            days = absRound(duration._days),
            months = absRound(duration._months);

        if (!mom.isValid()) {
            // No op
            return;
        }

        updateOffset = updateOffset == null ? true : updateOffset;

        if (milliseconds) {
            mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);
        }
        if (days) {
            get_set__set(mom, 'Date', get_set__get(mom, 'Date') + days * isAdding);
        }
        if (months) {
            setMonth(mom, get_set__get(mom, 'Month') + months * isAdding);
        }
        if (updateOffset) {
            utils_hooks__hooks.updateOffset(mom, days || months);
        }
    }

    var add_subtract__add = createAdder(1, 'add');
    var add_subtract__subtract = createAdder(-1, 'subtract');

    function getCalendarFormat(myMoment, now) {
        var diff = myMoment.diff(now, 'days', true);
        return diff < -6 ? 'sameElse' :
            diff < -1 ? 'lastWeek' :
            diff < 0 ? 'lastDay' :
            diff < 1 ? 'sameDay' :
            diff < 2 ? 'nextDay' :
            diff < 7 ? 'nextWeek' : 'sameElse';
    }

    function moment_calendar__calendar(time, formats) {
        // We want to compare the start of today, vs this.
        // Getting start-of-today depends on whether we're local/utc/offset or not.
        var now = time || local__createLocal(),
            sod = cloneWithOffset(now, this).startOf('day'),
            format = utils_hooks__hooks.calendarFormat(this, sod) || 'sameElse';

        var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]);

        return this.format(output || this.localeData().calendar(format, this, local__createLocal(now)));
    }

    function clone() {
        return new Moment(this);
    }

    function isAfter(input, units) {
        var localInput = isMoment(input) ? input : local__createLocal(input);
        if (!(this.isValid() && localInput.isValid())) {
            return false;
        }
        units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');
        if (units === 'millisecond') {
            return this.valueOf() > localInput.valueOf();
        } else {
            return localInput.valueOf() < this.clone().startOf(units).valueOf();
        }
    }

    function isBefore(input, units) {
        var localInput = isMoment(input) ? input : local__createLocal(input);
        if (!(this.isValid() && localInput.isValid())) {
            return false;
        }
        units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');
        if (units === 'millisecond') {
            return this.valueOf() < localInput.valueOf();
        } else {
            return this.clone().endOf(units).valueOf() < localInput.valueOf();
        }
    }

    function isBetween(from, to, units, inclusivity) {
        inclusivity = inclusivity || '()';
        return (inclusivity[0] === '(' ? this.isAfter(from, units) : !this.isBefore(from, units)) &&
            (inclusivity[1] === ')' ? this.isBefore(to, units) : !this.isAfter(to, units));
    }

    function isSame(input, units) {
        var localInput = isMoment(input) ? input : local__createLocal(input),
            inputMs;
        if (!(this.isValid() && localInput.isValid())) {
            return false;
        }
        units = normalizeUnits(units || 'millisecond');
        if (units === 'millisecond') {
            return this.valueOf() === localInput.valueOf();
        } else {
            inputMs = localInput.valueOf();
            return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();
        }
    }

    function isSameOrAfter(input, units) {
        return this.isSame(input, units) || this.isAfter(input, units);
    }

    function isSameOrBefore(input, units) {
        return this.isSame(input, units) || this.isBefore(input, units);
    }

    function diff(input, units, asFloat) {
        var that,
            zoneDelta,
            delta, output;

        if (!this.isValid()) {
            return NaN;
        }

        that = cloneWithOffset(input, this);

        if (!that.isValid()) {
            return NaN;
        }

        zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;

        units = normalizeUnits(units);

        if (units === 'year' || units === 'month' || units === 'quarter') {
            output = monthDiff(this, that);
            if (units === 'quarter') {
                output = output / 3;
            } else if (units === 'year') {
                output = output / 12;
            }
        } else {
            delta = this - that;
            output = units === 'second' ? delta / 1e3 : // 1000
                units === 'minute' ? delta / 6e4 : // 1000 * 60
                units === 'hour' ? delta / 36e5 : // 1000 * 60 * 60
                units === 'day' ? (delta - zoneDelta) / 864e5 : // 1000 * 60 * 60 * 24, negate dst
                units === 'week' ? (delta - zoneDelta) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst
                delta;
        }
        return asFloat ? output : absFloor(output);
    }

    function monthDiff(a, b) {
        // difference in months
        var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),
            // b is in (anchor - 1 month, anchor + 1 month)
            anchor = a.clone().add(wholeMonthDiff, 'months'),
            anchor2, adjust;

        if (b - anchor < 0) {
            anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');
            // linear across the month
            adjust = (b - anchor) / (anchor - anchor2);
        } else {
            anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');
            // linear across the month
            adjust = (b - anchor) / (anchor2 - anchor);
        }

        //check for negative zero, return zero if negative zero
        return -(wholeMonthDiff + adjust) || 0;
    }

    utils_hooks__hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';
    utils_hooks__hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';

    function toString() {
        return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
    }

    function moment_format__toISOString() {
        var m = this.clone().utc();
        if (0 < m.year() && m.year() <= 9999) {
            if (isFunction(Date.prototype.toISOString)) {
                // native implementation is ~50x faster, use it when we can
                return this.toDate().toISOString();
            } else {
                return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
            }
        } else {
            return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
        }
    }

    function format(inputString) {
        if (!inputString) {
            inputString = this.isUtc() ? utils_hooks__hooks.defaultFormatUtc : utils_hooks__hooks.defaultFormat;
        }
        var output = formatMoment(this, inputString);
        return this.localeData().postformat(output);
    }

    function from(time, withoutSuffix) {
        if (this.isValid() &&
            ((isMoment(time) && time.isValid()) ||
                local__createLocal(time).isValid())) {
            return create__createDuration({
                to: this,
                from: time
            }).locale(this.locale()).humanize(!withoutSuffix);
        } else {
            return this.localeData().invalidDate();
        }
    }

    function fromNow(withoutSuffix) {
        return this.from(local__createLocal(), withoutSuffix);
    }

    function to(time, withoutSuffix) {
        if (this.isValid() &&
            ((isMoment(time) && time.isValid()) ||
                local__createLocal(time).isValid())) {
            return create__createDuration({
                from: this,
                to: time
            }).locale(this.locale()).humanize(!withoutSuffix);
        } else {
            return this.localeData().invalidDate();
        }
    }

    function toNow(withoutSuffix) {
        return this.to(local__createLocal(), withoutSuffix);
    }

    // If passed a locale key, it will set the locale for this
    // instance.  Otherwise, it will return the locale configuration
    // variables for this instance.
    function locale(key) {
        var newLocaleData;

        if (key === undefined) {
            return this._locale._abbr;
        } else {
            newLocaleData = locale_locales__getLocale(key);
            if (newLocaleData != null) {
                this._locale = newLocaleData;
            }
            return this;
        }
    }

    var lang = deprecate(
        'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',
        function (key) {
            if (key === undefined) {
                return this.localeData();
            } else {
                return this.locale(key);
            }
        }
    );

    function localeData() {
        return this._locale;
    }

    function startOf(units) {
        units = normalizeUnits(units);
        // the following switch intentionally omits break keywords
        // to utilize falling through the cases.
        switch (units) {
            case 'year':
                this.month(0);
                /* falls through */
            case 'quarter':
            case 'month':
                this.date(1);
                /* falls through */
            case 'week':
            case 'isoWeek':
            case 'day':
            case 'date':
                this.hours(0);
                /* falls through */
            case 'hour':
                this.minutes(0);
                /* falls through */
            case 'minute':
                this.seconds(0);
                /* falls through */
            case 'second':
                this.milliseconds(0);
        }

        // weeks are a special case
        if (units === 'week') {
            this.weekday(0);
        }
        if (units === 'isoWeek') {
            this.isoWeekday(1);
        }

        // quarters are also special
        if (units === 'quarter') {
            this.month(Math.floor(this.month() / 3) * 3);
        }

        return this;
    }

    function endOf(units) {
        units = normalizeUnits(units);
        if (units === undefined || units === 'millisecond') {
            return this;
        }

        // 'date' is an alias for 'day', so it should be considered as such.
        if (units === 'date') {
            units = 'day';
        }

        return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');
    }

    function to_type__valueOf() {
        return this._d.valueOf() - ((this._offset || 0) * 60000);
    }

    function unix() {
        return Math.floor(this.valueOf() / 1000);
    }

    function toDate() {
        return new Date(this.valueOf());
    }

    function toArray() {
        var m = this;
        return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];
    }

    function toObject() {
        var m = this;
        return {
            years: m.year(),
            months: m.month(),
            date: m.date(),
            hours: m.hours(),
            minutes: m.minutes(),
            seconds: m.seconds(),
            milliseconds: m.milliseconds()
        };
    }

    function toJSON() {
        // new Date(NaN).toJSON() === null
        return this.isValid() ? this.toISOString() : null;
    }

    function moment_valid__isValid() {
        return valid__isValid(this);
    }

    function parsingFlags() {
        return extend({}, getParsingFlags(this));
    }

    function invalidAt() {
        return getParsingFlags(this).overflow;
    }

    function creationData() {
        return {
            input: this._i,
            format: this._f,
            locale: this._locale,
            isUTC: this._isUTC,
            strict: this._strict
        };
    }

    // FORMATTING

    addFormatToken(0, ['gg', 2], 0, function () {
        return this.weekYear() % 100;
    });

    addFormatToken(0, ['GG', 2], 0, function () {
        return this.isoWeekYear() % 100;
    });

    function addWeekYearFormatToken(token, getter) {
        addFormatToken(0, [token, token.length], 0, getter);
    }

    addWeekYearFormatToken('gggg', 'weekYear');
    addWeekYearFormatToken('ggggg', 'weekYear');
    addWeekYearFormatToken('GGGG', 'isoWeekYear');
    addWeekYearFormatToken('GGGGG', 'isoWeekYear');

    // ALIASES

    addUnitAlias('weekYear', 'gg');
    addUnitAlias('isoWeekYear', 'GG');

    // PRIORITY

    addUnitPriority('weekYear', 1);
    addUnitPriority('isoWeekYear', 1);


    // PARSING

    addRegexToken('G', matchSigned);
    addRegexToken('g', matchSigned);
    addRegexToken('GG', match1to2, match2);
    addRegexToken('gg', match1to2, match2);
    addRegexToken('GGGG', match1to4, match4);
    addRegexToken('gggg', match1to4, match4);
    addRegexToken('GGGGG', match1to6, match6);
    addRegexToken('ggggg', match1to6, match6);

    addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {
        week[token.substr(0, 2)] = toInt(input);
    });

    addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {
        week[token] = utils_hooks__hooks.parseTwoDigitYear(input);
    });

    // MOMENTS

    function getSetWeekYear(input) {
        return getSetWeekYearHelper.call(this,
            input,
            this.week(),
            this.weekday(),
            this.localeData()._week.dow,
            this.localeData()._week.doy);
    }

    function getSetISOWeekYear(input) {
        return getSetWeekYearHelper.call(this,
            input, this.isoWeek(), this.isoWeekday(), 1, 4);
    }

    function getISOWeeksInYear() {
        return weeksInYear(this.year(), 1, 4);
    }

    function getWeeksInYear() {
        var weekInfo = this.localeData()._week;
        return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
    }

    function getSetWeekYearHelper(input, week, weekday, dow, doy) {
        var weeksTarget;
        if (input == null) {
            return weekOfYear(this, dow, doy).year;
        } else {
            weeksTarget = weeksInYear(input, dow, doy);
            if (week > weeksTarget) {
                week = weeksTarget;
            }
            return setWeekAll.call(this, input, week, weekday, dow, doy);
        }
    }

    function setWeekAll(weekYear, week, weekday, dow, doy) {
        var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),
            date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);

        this.year(date.getUTCFullYear());
        this.month(date.getUTCMonth());
        this.date(date.getUTCDate());
        return this;
    }

    // FORMATTING

    addFormatToken('Q', 0, 'Qo', 'quarter');

    // ALIASES

    addUnitAlias('quarter', 'Q');

    // PRIORITY

    addUnitPriority('quarter', 7);

    // PARSING

    addRegexToken('Q', match1);
    addParseToken('Q', function (input, array) {
        array[MONTH] = (toInt(input) - 1) * 3;
    });

    // MOMENTS

    function getSetQuarter(input) {
        return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);
    }

    // FORMATTING

    addFormatToken('D', ['DD', 2], 'Do', 'date');

    // ALIASES

    addUnitAlias('date', 'D');

    // PRIOROITY
    addUnitPriority('date', 9);

    // PARSING

    addRegexToken('D', match1to2);
    addRegexToken('DD', match1to2, match2);
    addRegexToken('Do', function (isStrict, locale) {
        return isStrict ? locale._ordinalParse : locale._ordinalParseLenient;
    });

    addParseToken(['D', 'DD'], DATE);
    addParseToken('Do', function (input, array) {
        array[DATE] = toInt(input.match(match1to2)[0], 10);
    });

    // MOMENTS

    var getSetDayOfMonth = makeGetSet('Date', true);

    // FORMATTING

    addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');

    // ALIASES

    addUnitAlias('dayOfYear', 'DDD');

    // PRIORITY
    addUnitPriority('dayOfYear', 4);

    // PARSING

    addRegexToken('DDD', match1to3);
    addRegexToken('DDDD', match3);
    addParseToken(['DDD', 'DDDD'], function (input, array, config) {
        config._dayOfYear = toInt(input);
    });

    // HELPERS

    // MOMENTS

    function getSetDayOfYear(input) {
        var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;
        return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');
    }

    // FORMATTING

    addFormatToken('m', ['mm', 2], 0, 'minute');

    // ALIASES

    addUnitAlias('minute', 'm');

    // PRIORITY

    addUnitPriority('minute', 14);

    // PARSING

    addRegexToken('m', match1to2);
    addRegexToken('mm', match1to2, match2);
    addParseToken(['m', 'mm'], MINUTE);

    // MOMENTS

    var getSetMinute = makeGetSet('Minutes', false);

    // FORMATTING

    addFormatToken('s', ['ss', 2], 0, 'second');

    // ALIASES

    addUnitAlias('second', 's');

    // PRIORITY

    addUnitPriority('second', 15);

    // PARSING

    addRegexToken('s', match1to2);
    addRegexToken('ss', match1to2, match2);
    addParseToken(['s', 'ss'], SECOND);

    // MOMENTS

    var getSetSecond = makeGetSet('Seconds', false);

    // FORMATTING

    addFormatToken('S', 0, 0, function () {
        return ~~(this.millisecond() / 100);
    });

    addFormatToken(0, ['SS', 2], 0, function () {
        return ~~(this.millisecond() / 10);
    });

    addFormatToken(0, ['SSS', 3], 0, 'millisecond');
    addFormatToken(0, ['SSSS', 4], 0, function () {
        return this.millisecond() * 10;
    });
    addFormatToken(0, ['SSSSS', 5], 0, function () {
        return this.millisecond() * 100;
    });
    addFormatToken(0, ['SSSSSS', 6], 0, function () {
        return this.millisecond() * 1000;
    });
    addFormatToken(0, ['SSSSSSS', 7], 0, function () {
        return this.millisecond() * 10000;
    });
    addFormatToken(0, ['SSSSSSSS', 8], 0, function () {
        return this.millisecond() * 100000;
    });
    addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {
        return this.millisecond() * 1000000;
    });


    // ALIASES

    addUnitAlias('millisecond', 'ms');

    // PRIORITY

    addUnitPriority('millisecond', 16);

    // PARSING

    addRegexToken('S', match1to3, match1);
    addRegexToken('SS', match1to3, match2);
    addRegexToken('SSS', match1to3, match3);

    var token;
    for (token = 'SSSS'; token.length <= 9; token += 'S') {
        addRegexToken(token, matchUnsigned);
    }

    function parseMs(input, array) {
        array[MILLISECOND] = toInt(('0.' + input) * 1000);
    }

    for (token = 'S'; token.length <= 9; token += 'S') {
        addParseToken(token, parseMs);
    }
    // MOMENTS

    var getSetMillisecond = makeGetSet('Milliseconds', false);

    // FORMATTING

    addFormatToken('z', 0, 0, 'zoneAbbr');
    addFormatToken('zz', 0, 0, 'zoneName');

    // MOMENTS

    function getZoneAbbr() {
        return this._isUTC ? 'UTC' : '';
    }

    function getZoneName() {
        return this._isUTC ? 'Coordinated Universal Time' : '';
    }

    var momentPrototype__proto = Moment.prototype;

    momentPrototype__proto.add = add_subtract__add;
    momentPrototype__proto.calendar = moment_calendar__calendar;
    momentPrototype__proto.clone = clone;
    momentPrototype__proto.diff = diff;
    momentPrototype__proto.endOf = endOf;
    momentPrototype__proto.format = format;
    momentPrototype__proto.from = from;
    momentPrototype__proto.fromNow = fromNow;
    momentPrototype__proto.to = to;
    momentPrototype__proto.toNow = toNow;
    momentPrototype__proto.get = stringGet;
    momentPrototype__proto.invalidAt = invalidAt;
    momentPrototype__proto.isAfter = isAfter;
    momentPrototype__proto.isBefore = isBefore;
    momentPrototype__proto.isBetween = isBetween;
    momentPrototype__proto.isSame = isSame;
    momentPrototype__proto.isSameOrAfter = isSameOrAfter;
    momentPrototype__proto.isSameOrBefore = isSameOrBefore;
    momentPrototype__proto.isValid = moment_valid__isValid;
    momentPrototype__proto.lang = lang;
    momentPrototype__proto.locale = locale;
    momentPrototype__proto.localeData = localeData;
    momentPrototype__proto.max = prototypeMax;
    momentPrototype__proto.min = prototypeMin;
    momentPrototype__proto.parsingFlags = parsingFlags;
    momentPrototype__proto.set = stringSet;
    momentPrototype__proto.startOf = startOf;
    momentPrototype__proto.subtract = add_subtract__subtract;
    momentPrototype__proto.toArray = toArray;
    momentPrototype__proto.toObject = toObject;
    momentPrototype__proto.toDate = toDate;
    momentPrototype__proto.toISOString = moment_format__toISOString;
    momentPrototype__proto.toJSON = toJSON;
    momentPrototype__proto.toString = toString;
    momentPrototype__proto.unix = unix;
    momentPrototype__proto.valueOf = to_type__valueOf;
    momentPrototype__proto.creationData = creationData;

    // Year
    momentPrototype__proto.year = getSetYear;
    momentPrototype__proto.isLeapYear = getIsLeapYear;

    // Week Year
    momentPrototype__proto.weekYear = getSetWeekYear;
    momentPrototype__proto.isoWeekYear = getSetISOWeekYear;

    // Quarter
    momentPrototype__proto.quarter = momentPrototype__proto.quarters = getSetQuarter;

    // Month
    momentPrototype__proto.month = getSetMonth;
    momentPrototype__proto.daysInMonth = getDaysInMonth;

    // Week
    momentPrototype__proto.week = momentPrototype__proto.weeks = getSetWeek;
    momentPrototype__proto.isoWeek = momentPrototype__proto.isoWeeks = getSetISOWeek;
    momentPrototype__proto.weeksInYear = getWeeksInYear;
    momentPrototype__proto.isoWeeksInYear = getISOWeeksInYear;

    // Day
    momentPrototype__proto.date = getSetDayOfMonth;
    momentPrototype__proto.day = momentPrototype__proto.days = getSetDayOfWeek;
    momentPrototype__proto.weekday = getSetLocaleDayOfWeek;
    momentPrototype__proto.isoWeekday = getSetISODayOfWeek;
    momentPrototype__proto.dayOfYear = getSetDayOfYear;

    // Hour
    momentPrototype__proto.hour = momentPrototype__proto.hours = getSetHour;

    // Minute
    momentPrototype__proto.minute = momentPrototype__proto.minutes = getSetMinute;

    // Second
    momentPrototype__proto.second = momentPrototype__proto.seconds = getSetSecond;

    // Millisecond
    momentPrototype__proto.millisecond = momentPrototype__proto.milliseconds = getSetMillisecond;

    // Offset
    momentPrototype__proto.utcOffset = getSetOffset;
    momentPrototype__proto.utc = setOffsetToUTC;
    momentPrototype__proto.local = setOffsetToLocal;
    momentPrototype__proto.parseZone = setOffsetToParsedOffset;
    momentPrototype__proto.hasAlignedHourOffset = hasAlignedHourOffset;
    momentPrototype__proto.isDST = isDaylightSavingTime;
    momentPrototype__proto.isLocal = isLocal;
    momentPrototype__proto.isUtcOffset = isUtcOffset;
    momentPrototype__proto.isUtc = isUtc;
    momentPrototype__proto.isUTC = isUtc;

    // Timezone
    momentPrototype__proto.zoneAbbr = getZoneAbbr;
    momentPrototype__proto.zoneName = getZoneName;

    // Deprecations
    momentPrototype__proto.dates = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);
    momentPrototype__proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);
    momentPrototype__proto.years = deprecate('years accessor is deprecated. Use year instead', getSetYear);
    momentPrototype__proto.zone = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone);
    momentPrototype__proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted);

    var momentPrototype = momentPrototype__proto;

    function moment__createUnix(input) {
        return local__createLocal(input * 1000);
    }

    function moment__createInZone() {
        return local__createLocal.apply(null, arguments).parseZone();
    }

    function preParsePostFormat(string) {
        return string;
    }

    var prototype__proto = Locale.prototype;

    prototype__proto.calendar = locale_calendar__calendar;
    prototype__proto.longDateFormat = longDateFormat;
    prototype__proto.invalidDate = invalidDate;
    prototype__proto.ordinal = ordinal;
    prototype__proto.preparse = preParsePostFormat;
    prototype__proto.postformat = preParsePostFormat;
    prototype__proto.relativeTime = relative__relativeTime;
    prototype__proto.pastFuture = pastFuture;
    prototype__proto.set = locale_set__set;

    // Month
    prototype__proto.months = localeMonths;
    prototype__proto.monthsShort = localeMonthsShort;
    prototype__proto.monthsParse = localeMonthsParse;
    prototype__proto.monthsRegex = monthsRegex;
    prototype__proto.monthsShortRegex = monthsShortRegex;

    // Week
    prototype__proto.week = localeWeek;
    prototype__proto.firstDayOfYear = localeFirstDayOfYear;
    prototype__proto.firstDayOfWeek = localeFirstDayOfWeek;

    // Day of Week
    prototype__proto.weekdays = localeWeekdays;
    prototype__proto.weekdaysMin = localeWeekdaysMin;
    prototype__proto.weekdaysShort = localeWeekdaysShort;
    prototype__proto.weekdaysParse = localeWeekdaysParse;

    prototype__proto.weekdaysRegex = weekdaysRegex;
    prototype__proto.weekdaysShortRegex = weekdaysShortRegex;
    prototype__proto.weekdaysMinRegex = weekdaysMinRegex;

    // Hours
    prototype__proto.isPM = localeIsPM;
    prototype__proto.meridiem = localeMeridiem;

    function lists__get(format, index, field, setter) {
        var locale = locale_locales__getLocale();
        var utc = create_utc__createUTC().set(setter, index);
        return locale[field](utc, format);
    }

    function listMonthsImpl(format, index, field) {
        if (typeof format === 'number') {
            index = format;
            format = undefined;
        }

        format = format || '';

        if (index != null) {
            return lists__get(format, index, field, 'month');
        }

        var i;
        var out = [];
        for (i = 0; i < 12; i++) {
            out[i] = lists__get(format, i, field, 'month');
        }
        return out;
    }

    // ()
    // (5)
    // (fmt, 5)
    // (fmt)
    // (true)
    // (true, 5)
    // (true, fmt, 5)
    // (true, fmt)
    function listWeekdaysImpl(localeSorted, format, index, field) {
        if (typeof localeSorted === 'boolean') {
            if (typeof format === 'number') {
                index = format;
                format = undefined;
            }

            format = format || '';
        } else {
            format = localeSorted;
            index = format;
            localeSorted = false;

            if (typeof format === 'number') {
                index = format;
                format = undefined;
            }

            format = format || '';
        }

        var locale = locale_locales__getLocale(),
            shift = localeSorted ? locale._week.dow : 0;

        if (index != null) {
            return lists__get(format, (index + shift) % 7, field, 'day');
        }

        var i;
        var out = [];
        for (i = 0; i < 7; i++) {
            out[i] = lists__get(format, (i + shift) % 7, field, 'day');
        }
        return out;
    }

    function lists__listMonths(format, index) {
        return listMonthsImpl(format, index, 'months');
    }

    function lists__listMonthsShort(format, index) {
        return listMonthsImpl(format, index, 'monthsShort');
    }

    function lists__listWeekdays(localeSorted, format, index) {
        return listWeekdaysImpl(localeSorted, format, index, 'weekdays');
    }

    function lists__listWeekdaysShort(localeSorted, format, index) {
        return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');
    }

    function lists__listWeekdaysMin(localeSorted, format, index) {
        return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');
    }

    locale_locales__getSetGlobalLocale('en', {
        ordinalParse: /\d{1,2}(th|st|nd|rd)/,
        ordinal: function (number) {
            var b = number % 10,
                output = (toInt(number % 100 / 10) === 1) ? 'th' :
                (b === 1) ? 'st' :
                (b === 2) ? 'nd' :
                (b === 3) ? 'rd' : 'th';
            return number + output;
        }
    });

    // Side effect imports
    utils_hooks__hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', locale_locales__getSetGlobalLocale);
    utils_hooks__hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', locale_locales__getLocale);

    var mathAbs = Math.abs;

    function duration_abs__abs() {
        var data = this._data;

        this._milliseconds = mathAbs(this._milliseconds);
        this._days = mathAbs(this._days);
        this._months = mathAbs(this._months);

        data.milliseconds = mathAbs(data.milliseconds);
        data.seconds = mathAbs(data.seconds);
        data.minutes = mathAbs(data.minutes);
        data.hours = mathAbs(data.hours);
        data.months = mathAbs(data.months);
        data.years = mathAbs(data.years);

        return this;
    }

    function duration_add_subtract__addSubtract(duration, input, value, direction) {
        var other = create__createDuration(input, value);

        duration._milliseconds += direction * other._milliseconds;
        duration._days += direction * other._days;
        duration._months += direction * other._months;

        return duration._bubble();
    }

    // supports only 2.0-style add(1, 's') or add(duration)
    function duration_add_subtract__add(input, value) {
        return duration_add_subtract__addSubtract(this, input, value, 1);
    }

    // supports only 2.0-style subtract(1, 's') or subtract(duration)
    function duration_add_subtract__subtract(input, value) {
        return duration_add_subtract__addSubtract(this, input, value, -1);
    }

    function absCeil(number) {
        if (number < 0) {
            return Math.floor(number);
        } else {
            return Math.ceil(number);
        }
    }

    function bubble() {
        var milliseconds = this._milliseconds;
        var days = this._days;
        var months = this._months;
        var data = this._data;
        var seconds, minutes, hours, years, monthsFromDays;

        // if we have a mix of positive and negative values, bubble down first
        // check: https://github.com/moment/moment/issues/2166
        if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||
                (milliseconds <= 0 && days <= 0 && months <= 0))) {
            milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
            days = 0;
            months = 0;
        }

        // The following code bubbles up values, see the tests for
        // examples of what that means.
        data.milliseconds = milliseconds % 1000;

        seconds = absFloor(milliseconds / 1000);
        data.seconds = seconds % 60;

        minutes = absFloor(seconds / 60);
        data.minutes = minutes % 60;

        hours = absFloor(minutes / 60);
        data.hours = hours % 24;

        days += absFloor(hours / 24);

        // convert days to months
        monthsFromDays = absFloor(daysToMonths(days));
        months += monthsFromDays;
        days -= absCeil(monthsToDays(monthsFromDays));

        // 12 months -> 1 year
        years = absFloor(months / 12);
        months %= 12;

        data.days = days;
        data.months = months;
        data.years = years;

        return this;
    }

    function daysToMonths(days) {
        // 400 years have 146097 days (taking into account leap year rules)
        // 400 years have 12 months === 4800
        return days * 4800 / 146097;
    }

    function monthsToDays(months) {
        // the reverse of daysToMonths
        return months * 146097 / 4800;
    }

    function as(units) {
        var days;
        var months;
        var milliseconds = this._milliseconds;

        units = normalizeUnits(units);

        if (units === 'month' || units === 'year') {
            days = this._days + milliseconds / 864e5;
            months = this._months + daysToMonths(days);
            return units === 'month' ? months : months / 12;
        } else {
            // handle milliseconds separately because of floating point math errors (issue #1867)
            days = this._days + Math.round(monthsToDays(this._months));
            switch (units) {
                case 'week':
                    return days / 7 + milliseconds / 6048e5;
                case 'day':
                    return days + milliseconds / 864e5;
                case 'hour':
                    return days * 24 + milliseconds / 36e5;
                case 'minute':
                    return days * 1440 + milliseconds / 6e4;
                case 'second':
                    return days * 86400 + milliseconds / 1000;
                    // Math.floor prevents floating point math errors here
                case 'millisecond':
                    return Math.floor(days * 864e5) + milliseconds;
                default:
                    throw new Error('Unknown unit ' + units);
            }
        }
    }

    // TODO: Use this.as('ms')?
    function duration_as__valueOf() {
        return (
            this._milliseconds +
            this._days * 864e5 +
            (this._months % 12) * 2592e6 +
            toInt(this._months / 12) * 31536e6
        );
    }

    function makeAs(alias) {
        return function () {
            return this.as(alias);
        };
    }

    var asMilliseconds = makeAs('ms');
    var asSeconds = makeAs('s');
    var asMinutes = makeAs('m');
    var asHours = makeAs('h');
    var asDays = makeAs('d');
    var asWeeks = makeAs('w');
    var asMonths = makeAs('M');
    var asYears = makeAs('y');

    function duration_get__get(units) {
        units = normalizeUnits(units);
        return this[units + 's']();
    }

    function makeGetter(name) {
        return function () {
            return this._data[name];
        };
    }

    var milliseconds = makeGetter('milliseconds');
    var seconds = makeGetter('seconds');
    var minutes = makeGetter('minutes');
    var hours = makeGetter('hours');
    var days = makeGetter('days');
    var months = makeGetter('months');
    var years = makeGetter('years');

    function weeks() {
        return absFloor(this.days() / 7);
    }

    var round = Math.round;
    var thresholds = {
        s: 45, // seconds to minute
        m: 45, // minutes to hour
        h: 22, // hours to day
        d: 26, // days to month
        M: 11 // months to year
    };

    // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
    function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
        return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
    }

    function duration_humanize__relativeTime(posNegDuration, withoutSuffix, locale) {
        var duration = create__createDuration(posNegDuration).abs();
        var seconds = round(duration.as('s'));
        var minutes = round(duration.as('m'));
        var hours = round(duration.as('h'));
        var days = round(duration.as('d'));
        var months = round(duration.as('M'));
        var years = round(duration.as('y'));

        var a = seconds < thresholds.s && ['s', seconds] ||
            minutes <= 1 && ['m'] ||
            minutes < thresholds.m && ['mm', minutes] ||
            hours <= 1 && ['h'] ||
            hours < thresholds.h && ['hh', hours] ||
            days <= 1 && ['d'] ||
            days < thresholds.d && ['dd', days] ||
            months <= 1 && ['M'] ||
            months < thresholds.M && ['MM', months] ||
            years <= 1 && ['y'] || ['yy', years];

        a[2] = withoutSuffix;
        a[3] = +posNegDuration > 0;
        a[4] = locale;
        return substituteTimeAgo.apply(null, a);
    }

    // This function allows you to set the rounding function for relative time strings
    function duration_humanize__getSetRelativeTimeRounding(roundingFunction) {
        if (roundingFunction === undefined) {
            return round;
        }
        if (typeof (roundingFunction) === 'function') {
            round = roundingFunction;
            return true;
        }
        return false;
    }

    // This function allows you to set a threshold for relative time strings
    function duration_humanize__getSetRelativeTimeThreshold(threshold, limit) {
        if (thresholds[threshold] === undefined) {
            return false;
        }
        if (limit === undefined) {
            return thresholds[threshold];
        }
        thresholds[threshold] = limit;
        return true;
    }

    function humanize(withSuffix) {
        var locale = this.localeData();
        var output = duration_humanize__relativeTime(this, !withSuffix, locale);

        if (withSuffix) {
            output = locale.pastFuture(+this, output);
        }

        return locale.postformat(output);
    }

    var iso_string__abs = Math.abs;

    function iso_string__toISOString() {
        // for ISO strings we do not use the normal bubbling rules:
        //  * milliseconds bubble up until they become hours
        //  * days do not bubble at all
        //  * months bubble up until they become years
        // This is because there is no context-free conversion between hours and days
        // (think of clock changes)
        // and also not between days and months (28-31 days per month)
        var seconds = iso_string__abs(this._milliseconds) / 1000;
        var days = iso_string__abs(this._days);
        var months = iso_string__abs(this._months);
        var minutes, hours, years;

        // 3600 seconds -> 60 minutes -> 1 hour
        minutes = absFloor(seconds / 60);
        hours = absFloor(minutes / 60);
        seconds %= 60;
        minutes %= 60;

        // 12 months -> 1 year
        years = absFloor(months / 12);
        months %= 12;


        // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
        var Y = years;
        var M = months;
        var D = days;
        var h = hours;
        var m = minutes;
        var s = seconds;
        var total = this.asSeconds();

        if (!total) {
            // this is the same as C#'s (Noda) and python (isodate)...
            // but not other JS (goog.date)
            return 'P0D';
        }

        return (total < 0 ? '-' : '') +
            'P' +
            (Y ? Y + 'Y' : '') +
            (M ? M + 'M' : '') +
            (D ? D + 'D' : '') +
            ((h || m || s) ? 'T' : '') +
            (h ? h + 'H' : '') +
            (m ? m + 'M' : '') +
            (s ? s + 'S' : '');
    }

    var duration_prototype__proto = Duration.prototype;

    duration_prototype__proto.abs = duration_abs__abs;
    duration_prototype__proto.add = duration_add_subtract__add;
    duration_prototype__proto.subtract = duration_add_subtract__subtract;
    duration_prototype__proto.as = as;
    duration_prototype__proto.asMilliseconds = asMilliseconds;
    duration_prototype__proto.asSeconds = asSeconds;
    duration_prototype__proto.asMinutes = asMinutes;
    duration_prototype__proto.asHours = asHours;
    duration_prototype__proto.asDays = asDays;
    duration_prototype__proto.asWeeks = asWeeks;
    duration_prototype__proto.asMonths = asMonths;
    duration_prototype__proto.asYears = asYears;
    duration_prototype__proto.valueOf = duration_as__valueOf;
    duration_prototype__proto._bubble = bubble;
    duration_prototype__proto.get = duration_get__get;
    duration_prototype__proto.milliseconds = milliseconds;
    duration_prototype__proto.seconds = seconds;
    duration_prototype__proto.minutes = minutes;
    duration_prototype__proto.hours = hours;
    duration_prototype__proto.days = days;
    duration_prototype__proto.weeks = weeks;
    duration_prototype__proto.months = months;
    duration_prototype__proto.years = years;
    duration_prototype__proto.humanize = humanize;
    duration_prototype__proto.toISOString = iso_string__toISOString;
    duration_prototype__proto.toString = iso_string__toISOString;
    duration_prototype__proto.toJSON = iso_string__toISOString;
    duration_prototype__proto.locale = locale;
    duration_prototype__proto.localeData = localeData;

    // Deprecations
    duration_prototype__proto.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', iso_string__toISOString);
    duration_prototype__proto.lang = lang;

    // Side effect imports

    // FORMATTING

    addFormatToken('X', 0, 0, 'unix');
    addFormatToken('x', 0, 0, 'valueOf');

    // PARSING

    addRegexToken('x', matchSigned);
    addRegexToken('X', matchTimestamp);
    addParseToken('X', function (input, array, config) {
        config._d = new Date(parseFloat(input, 10) * 1000);
    });
    addParseToken('x', function (input, array, config) {
        config._d = new Date(toInt(input));
    });

    // Side effect imports


    utils_hooks__hooks.version = '2.15.2';

    setHookCallback(local__createLocal);

    utils_hooks__hooks.fn = momentPrototype;
    utils_hooks__hooks.min = min;
    utils_hooks__hooks.max = max;
    utils_hooks__hooks.now = now;
    utils_hooks__hooks.utc = create_utc__createUTC;
    utils_hooks__hooks.unix = moment__createUnix;
    utils_hooks__hooks.months = lists__listMonths;
    utils_hooks__hooks.isDate = isDate;
    utils_hooks__hooks.locale = locale_locales__getSetGlobalLocale;
    utils_hooks__hooks.invalid = valid__createInvalid;
    utils_hooks__hooks.duration = create__createDuration;
    utils_hooks__hooks.isMoment = isMoment;
    utils_hooks__hooks.weekdays = lists__listWeekdays;
    utils_hooks__hooks.parseZone = moment__createInZone;
    utils_hooks__hooks.localeData = locale_locales__getLocale;
    utils_hooks__hooks.isDuration = isDuration;
    utils_hooks__hooks.monthsShort = lists__listMonthsShort;
    utils_hooks__hooks.weekdaysMin = lists__listWeekdaysMin;
    utils_hooks__hooks.defineLocale = defineLocale;
    utils_hooks__hooks.updateLocale = updateLocale;
    utils_hooks__hooks.locales = locale_locales__listLocales;
    utils_hooks__hooks.weekdaysShort = lists__listWeekdaysShort;
    utils_hooks__hooks.normalizeUnits = normalizeUnits;
    utils_hooks__hooks.relativeTimeRounding = duration_humanize__getSetRelativeTimeRounding;
    utils_hooks__hooks.relativeTimeThreshold = duration_humanize__getSetRelativeTimeThreshold;
    utils_hooks__hooks.calendarFormat = getCalendarFormat;
    utils_hooks__hooks.prototype = momentPrototype;

    var _moment = utils_hooks__hooks;

    return _moment;

}));
define('moment', ['moment/moment'], function (main) {
    return main;
});

define('backend', ['fast', 'template', 'moment'], function (Fast, Template, Moment) {
    var Backend = {
        api: {
            sidebar: function (params) {
                colorArr = ['red', 'green', 'yellow', 'blue', 'teal', 'orange', 'purple'];
                $colorNums = colorArr.length;
                badgeList = {};
                $.each(params, function (k, v) {
                    $url = Fast.api.fixurl(k);

                    if ($.isArray(v)) {
                        $nums = typeof v[0] !== 'undefined' ? v[0] : 0;
                        $color = typeof v[1] !== 'undefined' ? v[1] : colorArr[(!isNaN($nums) ? $nums : $nums.length) % $colorNums];
                        $class = typeof v[2] !== 'undefined' ? v[2] : 'label';
                    } else {
                        $nums = v;
                        $color = colorArr[(!isNaN($nums) ? $nums : $nums.length) % $colorNums];
                        $class = 'label';
                    }
                    //必须nums大于0才显示
                    badgeList[$url] = $nums > 0 ? '<small class="' + $class + ' pull-right bg-' + $color + '">' + $nums + '</small>' : '';
                });
                $.each(badgeList, function (k, v) {
                    var anchor = top.window.$("li a[addtabs][url='" + k + "']");
                    if (anchor) {
                        top.window.$(".pull-right-container", anchor).html(v);
                        top.window.$(".nav-addtabs li a[node-id='" + anchor.attr("addtabs") + "'] .pull-right-container").html(v);
                    }
                });
            },
            addtabs: function (url, title, icon) {
                var dom = "a[url='{url}']"
                var leftlink = top.window.$(dom.replace(/\{url\}/, url));
                if (leftlink.size() > 0) {
                    leftlink.trigger("click");
                } else {
                    url = Fast.api.fixurl(url);
                    leftlink = top.window.$(dom.replace(/\{url\}/, url));
                    if (leftlink.size() > 0) {
                        var event = leftlink.parent().hasClass("active") ? "dblclick" : "click";
                        leftlink.trigger(event);
                    } else {
                        var baseurl = url.substr(0, url.indexOf("?") > -1 ? url.indexOf("?") : url.length);
                        leftlink = top.window.$(dom.replace(/\{url\}/, baseurl));
                        //能找到相对地址
                        if (leftlink.size() > 0) {
                            icon = typeof icon !== 'undefined' ? icon : leftlink.find("i").attr("class");
                            title = typeof title !== 'undefined' ? title : leftlink.find("span:first").text();
                            leftlink.trigger("fa.event.toggleitem");
                        }
                        var navnode = top.window.$(".nav-tabs ul li a[node-url='" + url + "']");
                        if (navnode.size() > 0) {
                            navnode.trigger("click");
                        } else {
                            //追加新的tab
                            var id = Math.floor(new Date().valueOf() * Math.random());
                            icon = typeof icon !== 'undefined' ? icon : 'fa fa-circle-o';
                            title = typeof title !== 'undefined' ? title : '';
                            top.window.$("<a />").append('<i class="' + icon + '"></i> <span>' + title + '</span>').prop("href", url).attr({
                                url: url,
                                addtabs: id
                            }).addClass("hide").appendTo(top.window.document.body).trigger("click");
                        }
                    }
                }
            },
            closetabs: function (url) {
                if (typeof url === 'undefined') {
                    top.window.$("ul.nav-addtabs li.active .close-tab").trigger("click");
                } else {
                    var dom = "a[url='{url}']"
                    var navlink = top.window.$(dom.replace(/\{url\}/, url));
                    if (navlink.size() === 0) {
                        url = Fast.api.fixurl(url);
                        navlink = top.window.$(dom.replace(/\{url\}/, url));
                        if (navlink.size() === 0) {} else {
                            var baseurl = url.substr(0, url.indexOf("?") > -1 ? url.indexOf("?") : url.length);
                            navlink = top.window.$(dom.replace(/\{url\}/, baseurl));
                            //能找到相对地址
                            if (navlink.size() === 0) {
                                navlink = top.window.$(".nav-tabs ul li a[node-url='" + url + "']");
                            }
                        }
                    }
                    if (navlink.size() > 0 && navlink.attr('addtabs')) {
                        top.window.$("ul.nav-addtabs li#tab_" + navlink.attr('addtabs') + " .close-tab").trigger("click");
                    }
                }
            },
            replaceids: function (elem, url) {
                //如果有需要替换ids的
                if (url.indexOf("{ids}") > -1) {
                    var ids = 0;
                    var tableId = $(elem).data("table-id");
                    if (tableId && $(tableId).size() > 0 && $(tableId).data("bootstrap.table")) {
                        var Table = require("table");
                        ids = Table.api.selectedids($(tableId)).join(",");
                    }
                    url = url.replace(/\{ids\}/g, ids);
                }
                return url;
            },
            refreshmenu: function () {
                top.window.$(".sidebar-menu").trigger("refresh");
            },
            gettablecolumnbutton: function (options) {
                if (typeof options.tableId !== 'undefined' && typeof options.fieldIndex !== 'undefined' && typeof options.buttonIndex !== 'undefined') {
                    var tableOptions = $("#" + options.tableId).bootstrapTable('getOptions');
                    if (tableOptions) {
                        var columnObj = null;
                        $.each(tableOptions.columns, function (i, columns) {
                            $.each(columns, function (j, column) {
                                if (typeof column.fieldIndex !== 'undefined' && column.fieldIndex === options.fieldIndex) {
                                    columnObj = column;
                                    return false;
                                }
                            });
                            if (columnObj) {
                                return false;
                            }
                        });
                        if (columnObj) {
                            return columnObj['buttons'][options.buttonIndex];
                        }
                    }
                }
                return null;
            },
        },
        init: function () {
            $(document).on('click', '.btn-ajax-callback', function (e) {
                var that = this;
                var options = $.extend({}, $(that).data() || {});
                if (typeof options.url === 'undefined' && $(that).attr("href")) {
                    options.url = $(that).attr("href");
                }
                options.url = Backend.api.replaceids(this, options.url);
                var success = typeof options.success !== 'undefined' ? options.success : function () {
                    try {
                        $("#" + options.tableid).bootstrapTable('refresh');
                    } catch (e) {

                    }
                };
                var error = typeof options.error !== 'undefined' ? options.error : null;
                Backend.api.ajax(options, function () {
                    try {
                        if (typeof success === "function") {
                            success()
                        } else {
                            eval(success)();
                        }
                    } catch (e) {
                        console.log(e)
                    }
                    Layer.closeAll()
                }, error);
                return false;
            });

            //公共代码
            //添加ios-fix兼容iOS下的iframe
            if (/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream) {
                $("html").addClass("ios-fix");
            }
            //配置Toastr的参数
            Toastr.options.positionClass = Config.controllername === 'index' ? "toast-top-right-index" : "toast-top-right";
            //点击包含.btn-dialog的元素时弹出dialog
            $(document).on('click', '.btn-dialog,.dialogit', function (e) {
                var that = this;
                var options = $.extend({}, $(that).data() || {});
                var url = Backend.api.replaceids(that, $(that).attr('href'));
                var title = $(that).attr("title") || $(that).data("title") || $(that).data('original-title');
                var button = Backend.api.gettablecolumnbutton(options);
                if (button && typeof button.callback === 'function') {
                    options.callback = button.callback;
                }
                if (typeof options.confirm !== 'undefined') {
                    Layer.confirm(options.confirm, function (index) {
                        Backend.api.open(url, title, options);
                        Layer.close(index);
                    });
                } else {
                    Backend.api.open(url, title, options);
                }
                return false;
            });
            //点击包含.btn-addtabs的元素时新增选项卡
            $(document).on('click', '.btn-addtabs,.addtabsit', function (e) {
                var that = this;
                var options = $.extend({}, $(that).data() || {});
                var url = Backend.api.replaceids(that, $(that).attr('href'));
                var title = $(that).attr("title") || $(that).data("title") || $(that).data('original-title');
                if (typeof options.confirm !== 'undefined') {
                    Layer.confirm(options.confirm, function (index) {
                        Backend.api.addtabs(url, title);
                        Layer.close(index);
                    });
                } else {
                    Backend.api.addtabs(url, title);
                }
                return false;
            });
            //点击包含.btn-ajax的元素时发送Ajax请求
            $(document).on('click', '.btn-ajax,.ajaxit', function (e) {
                var that = this;
                var options = $.extend({}, $(that).data() || {});
                if (typeof options.url === 'undefined' && $(that).attr("href")) {
                    options.url = $(that).attr("href");
                }
                options.url = Backend.api.replaceids(this, options.url);
                var success = typeof options.success === 'function' ? options.success : null;
                var error = typeof options.error === 'function' ? options.error : null;
                delete options.success;
                delete options.error;
                var button = Backend.api.gettablecolumnbutton(options);
                if (button) {
                    if (typeof button.success === 'function') {
                        success = button.success;
                    }
                    if (typeof button.error === 'function') {
                        error = button.error;
                    }
                }
                //如果未设备成功的回调,设定了自动刷新的情况下自动进行刷新
                if (!success && typeof options.tableId !== 'undefined' && typeof options.refresh !== 'undefined' && options.refresh) {
                    $("#" + options.tableId).bootstrapTable('refresh');
                }
                if (typeof options.confirm !== 'undefined') {
                    Layer.confirm(options.confirm, function (index) {
                        Backend.api.ajax(options, success, error);
                        Layer.close(index);
                    });
                } else {
                    Backend.api.ajax(options, success, error);
                }
                return false;
            });
            //填充商品信息
            $(document).on('click', ".btn-goods-info", function (e) {
                var goods_url = $("#c-goods_url");
                var url = goods_url.val();
                if (!url) {
                    goods_url.focus();
                    Toastr.error('商品信息未设置')
                    return;
                }
                var idx1 = layer.load(1, {
                    shade: [0.1, '#000']
                });
                var form = $(this).closest("form");
                Fast.api.ajax({
                    url: "goods/customall/getShopInfo?union=1",
                    data: form.serialize(),
                }, function (data, ret) {
                    layer.close(idx1);
                    $("#c-goods_id").val(data.num_iid);
                    $('#c-title').val(data.title);
                    $('#c-rowimage').val(data.pict_url).change();
                    $('#c-origin_price').val(data.origin_price); /*原价*/
                    $('#c-quan_price').val(data.quan_price); /*券价*/
                    $("#c-final_price").val(data.coupon_price); /*券后价*/
                    $("#c-coupon_link").val(data.quan_link);
                    $("#c-tkrate").val(data.tkrates); /*佣金比例*/
                    if (data.coupon_start_time) {
                        $('#c-starttime').val(data.coupon_start_time); /*优惠券开始时间*/
                    }
                    if (data.quan_start_time) {
                        $('#c-starttime').val(data.quan_start_time); /*优惠券开始时间*/
                    }
                    if (data.coupon_end_time) {
                        $('#c-endtime').val(data.coupon_end_time); /*优惠券结束时间*/
                    }
                    if (data.quan_time) {
                        $('#c-endtime').val(data.quan_time); /*优惠券结束时间*/
                    }
                    $("#c-quan_id").val(data.quan_id);
                    Toastr.success('获取商品信息成功')
                    return false;
                }, function (data, ret) {
                    Toastr.error(ret.msg)
                    return false;
                });
            });
            //修复含有fixed-footer类的body边距
            if ($(".fixed-footer").size() > 0) {
                $(document.body).css("padding-bottom", $(".fixed-footer").outerHeight());
            }
            //修复不在iframe时layer-footer隐藏的问题
            if ($(".layer-footer").size() > 0 && self === top) {
                $(".layer-footer").show();
            }
            //优化在多个弹窗下点击不能切换的操作体验
            if (Fast.api.query("dialog") == "1" && self != top && self.frameElement && self.frameElement.tagName == "IFRAME") {
                $(window).on('click', function () {
                    var layero = self.frameElement.parentNode.parentElement;
                    if (parent.Layer.zIndex != parseInt(parent.window.$(layero).css("z-index"))) {
                        parent.window.$(layero).trigger("mousedown");
                        parent.Layer.zIndex = parseInt(parent.window.$(layero).css("z-index"));
                    }
                });
            }
            //tooltip和popover
            if (!('ontouchstart' in document.documentElement)) {
                $('body').tooltip({
                    selector: '[data-toggle="tooltip"]'
                });
            }
            $('body').popover({
                selector: '[data-toggle="popover"]'
            });
        }
    };
    Backend.api = $.extend(Fast.api, Backend.api);
    //将Template渲染至全局,以便于在子框架中调用
    window.Template = Template;
    //将Moment渲染至全局,以便于在子框架中调用
    window.Moment = Moment;
    //将Backend渲染至全局,以便于在子框架中调用
    window.Backend = Backend;

    Backend.init();
    return Backend;
});
/*
 * bootstrap-table - v1.11.1 - 2017-02-22
 * https://github.com/wenzhixin/bootstrap-table
 * Copyright (c) 2017 zhixin wen
 * Licensed MIT License
 */
! function (a) {
    "use strict";
    var b = null,
        c = function (a) {
            var b = arguments,
                c = !0,
                d = 1;
            return a = a.replace(/%s/g, function () {
                var a = b[d++];
                return "undefined" == typeof a ? (c = !1, "") : a
            }), c ? a : ""
        },
        d = function (b, c, d, e) {
            var f = "";
            return a.each(b, function (a, b) {
                return b[c] === e ? (f = b[d], !1) : !0
            }), f
        },
        e = function (b, c) {
            var d = -1;
            return a.each(b, function (a, b) {
                return b.field === c ? (d = a, !1) : !0
            }), d
        },
        f = function (b) {
            var c, d, e, f = 0,
                g = [];
            for (c = 0; c < b[0].length; c++) f += b[0][c].colspan || 1;
            for (c = 0; c < b.length; c++)
                for (g[c] = [], d = 0; f > d; d++) g[c][d] = !1;
            for (c = 0; c < b.length; c++)
                for (d = 0; d < b[c].length; d++) {
                    var h = b[c][d],
                        i = h.rowspan || 1,
                        j = h.colspan || 1,
                        k = a.inArray(!1, g[c]);
                    for (1 === j && (h.fieldIndex = k, "undefined" == typeof h.field && (h.field = k)), e = 0; i > e; e++) g[c + e][k] = !0;
                    for (e = 0; j > e; e++) g[c][k + e] = !0
                }
        },
        g = function () {
            if (null === b) {
                var c, d, e = a("<p/>").addClass("fixed-table-scroll-inner"),
                    f = a("<div/>").addClass("fixed-table-scroll-outer");
                f.append(e), a("body").append(f), c = e[0].offsetWidth, f.css("overflow", "scroll"), d = e[0].offsetWidth, c === d && (d = f[0].clientWidth), f.remove(), b = c - d
            }
            return b
        },
        h = function (b, d, e, f) {
            var g = d;
            if ("string" == typeof d) {
                var h = d.split(".");
                h.length > 1 ? (g = window, a.each(h, function (a, b) {
                    g = g[b]
                })) : g = window[d]
            }
            return "object" == typeof g ? g : "function" == typeof g ? g.apply(b, e || []) : !g && "string" == typeof d && c.apply(this, [d].concat(e)) ? c.apply(this, [d].concat(e)) : f
        },
        i = function (b, c, d) {
            var e = Object.getOwnPropertyNames(b),
                f = Object.getOwnPropertyNames(c),
                g = "";
            if (d && e.length !== f.length) return !1;
            for (var h = 0; h < e.length; h++)
                if (g = e[h], a.inArray(g, f) > -1 && b[g] !== c[g]) return !1;
            return !0
        },
        j = function (a) {
            return "string" == typeof a ? a.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;").replace(/`/g, "&#x60;") : a
        },
        k = function (a) {
            for (var b in a) {
                var c = b.split(/(?=[A-Z])/).join("-").toLowerCase();
                c !== b && (a[c] = a[b], delete a[b])
            }
            return a
        },
        l = function (a, b, c) {
            var d = a;
            if ("string" != typeof b || a.hasOwnProperty(b)) return c ? j(a[b]) : a[b];
            var e = b.split(".");
            for (var f in e) e.hasOwnProperty(f) && (d = d && d[e[f]]);
            return c ? j(d) : d
        },
        m = function () {
            return !!(navigator.userAgent.indexOf("MSIE ") > 0 || navigator.userAgent.match(/Trident.*rv\:11\./))
        },
        n = function () {
            Object.keys || (Object.keys = function () {
                var a = Object.prototype.hasOwnProperty,
                    b = !{
                        toString: null
                    }.propertyIsEnumerable("toString"),
                    c = ["toString", "toLocaleString", "valueOf", "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable", "constructor"],
                    d = c.length;
                return function (e) {
                    if ("object" != typeof e && ("function" != typeof e || null === e)) throw new TypeError("Object.keys called on non-object");
                    var f, g, h = [];
                    for (f in e) a.call(e, f) && h.push(f);
                    if (b)
                        for (g = 0; d > g; g++) a.call(e, c[g]) && h.push(c[g]);
                    return h
                }
            }())
        },
        o = function (b, c) {
            this.options = c, this.$el = a(b), this.$el_ = this.$el.clone(), this.timeoutId_ = 0, this.timeoutFooter_ = 0, this.init()
        };
    o.DEFAULTS = {
        classes: "table table-hover",
        sortClass: void 0,
        locale: void 0,
        height: void 0,
        undefinedText: "-",
        sortName: void 0,
        sortOrder: "asc",
        sortStable: !1,
        striped: !1,
        columns: [
            []
        ],
        data: [],
        totalField: "total",
        dataField: "rows",
        method: "get",
        url: void 0,
        ajax: void 0,
        cache: !0,
        contentType: "application/json",
        dataType: "json",
        ajaxOptions: {},
        queryParams: function (a) {
            return a
        },
        queryParamsType: "limit",
        responseHandler: function (a) {
            return a
        },
        pagination: !1,
        onlyInfoPagination: !1,
        paginationLoop: !0,
        sidePagination: "client",
        totalRows: 0,
        pageNumber: 1,
        pageSize: 10,
        pageList: [10, 25, 50, 100],
        paginationHAlign: "right",
        paginationVAlign: "bottom",
        paginationDetailHAlign: "left",
        paginationPreText: "&lsaquo;",
        paginationNextText: "&rsaquo;",
        search: !1,
        searchOnEnterKey: !1,
        strictSearch: !1,
        searchAlign: "right",
        selectItemName: "btSelectItem",
        showHeader: !0,
        showFooter: !1,
        showColumns: !1,
        showPaginationSwitch: !1,
        showRefresh: !1,
        showToggle: !1,
        buttonsAlign: "right",
        smartDisplay: !0,
        escape: !1,
        minimumCountColumns: 1,
        idField: void 0,
        uniqueId: void 0,
        cardView: !1,
        detailView: !1,
        detailFormatter: function () {
            return ""
        },
        trimOnSearch: !0,
        clickToSelect: !1,
        singleSelect: !1,
        toolbar: void 0,
        toolbarAlign: "left",
        checkboxHeader: !0,
        sortable: !0,
        silentSort: !0,
        maintainSelected: !1,
        searchTimeOut: 500,
        searchText: "",
        iconSize: void 0,
        buttonsClass: "default",
        iconsPrefix: "glyphicon",
        icons: {
            paginationSwitchDown: "glyphicon-collapse-down icon-chevron-down",
            paginationSwitchUp: "glyphicon-collapse-up icon-chevron-up",
            refresh: "glyphicon-refresh icon-refresh",
            toggle: "glyphicon-list-alt icon-list-alt",
            columns: "glyphicon-th icon-th",
            detailOpen: "glyphicon-plus icon-plus",
            detailClose: "glyphicon-minus icon-minus"
        },
        customSearch: a.noop,
        customSort: a.noop,
        rowStyle: function () {
            return {}
        },
        rowAttributes: function () {
            return {}
        },
        footerStyle: function () {
            return {}
        },
        onAll: function () {
            return !1
        },
        onClickCell: function () {
            return !1
        },
        onDblClickCell: function () {
            return !1
        },
        onClickRow: function () {
            return !1
        },
        onDblClickRow: function () {
            return !1
        },
        onSort: function () {
            return !1
        },
        onCheck: function () {
            return !1
        },
        onUncheck: function () {
            return !1
        },
        onCheckAll: function () {
            return !1
        },
        onUncheckAll: function () {
            return !1
        },
        onCheckSome: function () {
            return !1
        },
        onUncheckSome: function () {
            return !1
        },
        onLoadSuccess: function () {
            return !1
        },
        onLoadError: function () {
            return !1
        },
        onColumnSwitch: function () {
            return !1
        },
        onPageChange: function () {
            return !1
        },
        onSearch: function () {
            return !1
        },
        onToggle: function () {
            return !1
        },
        onPreBody: function () {
            return !1
        },
        onPostBody: function () {
            return !1
        },
        onPostHeader: function () {
            return !1
        },
        onExpandRow: function () {
            return !1
        },
        onCollapseRow: function () {
            return !1
        },
        onRefreshOptions: function () {
            return !1
        },
        onRefresh: function () {
            return !1
        },
        onResetView: function () {
            return !1
        }
    }, o.LOCALES = {}, o.LOCALES["en-US"] = o.LOCALES.en = {
        formatLoadingMessage: function () {
            return "Loading, please wait..."
        },
        formatRecordsPerPage: function (a) {
            return c("%s rows per page", a)
        },
        formatShowingRows: function (a, b, d) {
            return c("Showing %s to %s of %s rows", a, b, d)
        },
        formatDetailPagination: function (a) {
            return c("Showing %s rows", a)
        },
        formatSearch: function () {
            return "Search"
        },
        formatNoMatches: function () {
            return "No matching records found"
        },
        formatPaginationSwitch: function () {
            return "Hide/Show pagination"
        },
        formatRefresh: function () {
            return "Refresh"
        },
        formatToggle: function () {
            return "Toggle"
        },
        formatColumns: function () {
            return "Columns"
        },
        formatAllRows: function () {
            return "All"
        }
    }, a.extend(o.DEFAULTS, o.LOCALES["en-US"]), o.COLUMN_DEFAULTS = {
        radio: !1,
        checkbox: !1,
        checkboxEnabled: !0,
        field: void 0,
        title: void 0,
        titleTooltip: void 0,
        "class": void 0,
        align: void 0,
        halign: void 0,
        falign: void 0,
        valign: void 0,
        width: void 0,
        sortable: !1,
        order: "asc",
        visible: !0,
        switchable: !0,
        clickToSelect: !0,
        formatter: void 0,
        footerFormatter: void 0,
        events: void 0,
        sorter: void 0,
        sortName: void 0,
        cellStyle: void 0,
        searchable: !0,
        searchFormatter: !0,
        cardVisible: !0,
        escape: !1
    }, o.EVENTS = {
        "all.bs.table": "onAll",
        "click-cell.bs.table": "onClickCell",
        "dbl-click-cell.bs.table": "onDblClickCell",
        "click-row.bs.table": "onClickRow",
        "dbl-click-row.bs.table": "onDblClickRow",
        "sort.bs.table": "onSort",
        "check.bs.table": "onCheck",
        "uncheck.bs.table": "onUncheck",
        "check-all.bs.table": "onCheckAll",
        "uncheck-all.bs.table": "onUncheckAll",
        "check-some.bs.table": "onCheckSome",
        "uncheck-some.bs.table": "onUncheckSome",
        "load-success.bs.table": "onLoadSuccess",
        "load-error.bs.table": "onLoadError",
        "column-switch.bs.table": "onColumnSwitch",
        "page-change.bs.table": "onPageChange",
        "search.bs.table": "onSearch",
        "toggle.bs.table": "onToggle",
        "pre-body.bs.table": "onPreBody",
        "post-body.bs.table": "onPostBody",
        "post-header.bs.table": "onPostHeader",
        "expand-row.bs.table": "onExpandRow",
        "collapse-row.bs.table": "onCollapseRow",
        "refresh-options.bs.table": "onRefreshOptions",
        "reset-view.bs.table": "onResetView",
        "refresh.bs.table": "onRefresh"
    }, o.prototype.init = function () {
        this.initLocale(), this.initContainer(), this.initTable(), this.initHeader(), this.initData(), this.initHiddenRows(), this.initFooter(), this.initToolbar(), this.initPagination(), this.initBody(), this.initSearchText(), this.initServer()
    }, o.prototype.initLocale = function () {
        if (this.options.locale) {
            var b = this.options.locale.split(/-|_/);
            b[0].toLowerCase(), b[1] && b[1].toUpperCase(), a.fn.bootstrapTable.locales[this.options.locale] ? a.extend(this.options, a.fn.bootstrapTable.locales[this.options.locale]) : a.fn.bootstrapTable.locales[b.join("-")] ? a.extend(this.options, a.fn.bootstrapTable.locales[b.join("-")]) : a.fn.bootstrapTable.locales[b[0]] && a.extend(this.options, a.fn.bootstrapTable.locales[b[0]])
        }
    }, o.prototype.initContainer = function () {
        this.$container = a(['<div class="bootstrap-table">', '<div class="fixed-table-toolbar"></div>', "top" === this.options.paginationVAlign || "both" === this.options.paginationVAlign ? '<div class="fixed-table-pagination" style="clear: both;"></div>' : "", '<div class="fixed-table-container">', '<div class="fixed-table-header"><table></table></div>', '<div class="fixed-table-body">', '<div class="fixed-table-loading">', this.options.formatLoadingMessage(), "</div>", "</div>", '<div class="fixed-table-footer"><table><tr></tr></table></div>', "bottom" === this.options.paginationVAlign || "both" === this.options.paginationVAlign ? '<div class="fixed-table-pagination"></div>' : "", "</div>", "</div>"].join("")), this.$container.insertAfter(this.$el), this.$tableContainer = this.$container.find(".fixed-table-container"), this.$tableHeader = this.$container.find(".fixed-table-header"), this.$tableBody = this.$container.find(".fixed-table-body"), this.$tableLoading = this.$container.find(".fixed-table-loading"), this.$tableFooter = this.$container.find(".fixed-table-footer"), this.$toolbar = this.$container.find(".fixed-table-toolbar"), this.$pagination = this.$container.find(".fixed-table-pagination"), this.$tableBody.append(this.$el), this.$container.after('<div class="clearfix"></div>'), this.$el.addClass(this.options.classes), this.options.striped && this.$el.addClass("table-striped"), -1 !== a.inArray("table-no-bordered", this.options.classes.split(" ")) && this.$tableContainer.addClass("table-no-bordered")
    }, o.prototype.initTable = function () {
        var b = this,
            c = [],
            d = [];
        if (this.$header = this.$el.find(">thead"), this.$header.length || (this.$header = a("<thead></thead>").appendTo(this.$el)), this.$header.find("tr").each(function () {
                var b = [];
                a(this).find("th").each(function () {
                    "undefined" != typeof a(this).data("field") && a(this).data("field", a(this).data("field") + ""), b.push(a.extend({}, {
                        title: a(this).html(),
                        "class": a(this).attr("class"),
                        titleTooltip: a(this).attr("title"),
                        rowspan: a(this).attr("rowspan") ? +a(this).attr("rowspan") : void 0,
                        colspan: a(this).attr("colspan") ? +a(this).attr("colspan") : void 0
                    }, a(this).data()))
                }), c.push(b)
            }), a.isArray(this.options.columns[0]) || (this.options.columns = [this.options.columns]), this.options.columns = a.extend(!0, [], c, this.options.columns), this.columns = [], f(this.options.columns), a.each(this.options.columns, function (c, d) {
                a.each(d, function (d, e) {
                    e = a.extend({}, o.COLUMN_DEFAULTS, e), "undefined" != typeof e.fieldIndex && (b.columns[e.fieldIndex] = e), b.options.columns[c][d] = e
                })
            }), !this.options.data.length) {
            var e = [];
            this.$el.find(">tbody>tr").each(function (c) {
                var f = {};
                f._id = a(this).attr("id"), f._class = a(this).attr("class"), f._data = k(a(this).data()), a(this).find(">td").each(function (d) {
                    for (var g, h, i = a(this), j = +i.attr("colspan") || 1, l = +i.attr("rowspan") || 1; e[c] && e[c][d]; d++);
                    for (g = d; d + j > g; g++)
                        for (h = c; c + l > h; h++) e[h] || (e[h] = []), e[h][g] = !0;
                    var m = b.columns[d].field;
                    f[m] = a(this).html(), f["_" + m + "_id"] = a(this).attr("id"), f["_" + m + "_class"] = a(this).attr("class"), f["_" + m + "_rowspan"] = a(this).attr("rowspan"), f["_" + m + "_colspan"] = a(this).attr("colspan"), f["_" + m + "_title"] = a(this).attr("title"), f["_" + m + "_data"] = k(a(this).data())
                }), d.push(f)
            }), this.options.data = d, d.length && (this.fromHtml = !0)
        }
    }, o.prototype.initHeader = function () {
        var b = this,
            d = {},
            e = [];
        this.header = {
            fields: [],
            styles: [],
            classes: [],
            formatters: [],
            events: [],
            sorters: [],
            sortNames: [],
            cellStyles: [],
            searchables: []
        }, a.each(this.options.columns, function (f, g) {
            e.push("<tr>"), 0 === f && !b.options.cardView && b.options.detailView && e.push(c('<th class="detail" rowspan="%s"><div class="fht-cell"></div></th>', b.options.columns.length)), a.each(g, function (a, f) {
                var g = "",
                    h = "",
                    i = "",
                    k = "",
                    l = c(' class="%s"', f["class"]),
                    m = (b.options.sortOrder || f.order, "px"),
                    n = f.width;
                if (void 0 === f.width || b.options.cardView || "string" == typeof f.width && -1 !== f.width.indexOf("%") && (m = "%"), f.width && "string" == typeof f.width && (n = f.width.replace("%", "").replace("px", "")), h = c("text-align: %s; ", f.halign ? f.halign : f.align), i = c("text-align: %s; ", f.align), k = c("vertical-align: %s; ", f.valign), k += c("width: %s; ", !f.checkbox && !f.radio || n ? n ? n + m : void 0 : "36px"), "undefined" != typeof f.fieldIndex) {
                    if (b.header.fields[f.fieldIndex] = f.field, b.header.styles[f.fieldIndex] = i + k, b.header.classes[f.fieldIndex] = l, b.header.formatters[f.fieldIndex] = f.formatter, b.header.events[f.fieldIndex] = f.events, b.header.sorters[f.fieldIndex] = f.sorter, b.header.sortNames[f.fieldIndex] = f.sortName, b.header.cellStyles[f.fieldIndex] = f.cellStyle, b.header.searchables[f.fieldIndex] = f.searchable, !f.visible) return;
                    if (b.options.cardView && !f.cardVisible) return;
                    d[f.field] = f
                }
                e.push("<th" + c(' title="%s"', f.titleTooltip), f.checkbox || f.radio ? c(' class="bs-checkbox %s"', f["class"] || "") : l, c(' style="%s"', h + k), c(' rowspan="%s"', f.rowspan), c(' colspan="%s"', f.colspan), c(' data-field="%s"', f.field), ">"), e.push(c('<div class="th-inner %s">', b.options.sortable && f.sortable ? "sortable both" : "")), g = b.options.escape ? j(f.title) : f.title, f.checkbox && (!b.options.singleSelect && b.options.checkboxHeader && (g = '<input name="btSelectAll" type="checkbox" />'), b.header.stateField = f.field), f.radio && (g = "", b.header.stateField = f.field, b.options.singleSelect = !0), e.push(g), e.push("</div>"), e.push('<div class="fht-cell"></div>'), e.push("</div>"), e.push("</th>")
            }), e.push("</tr>")
        }), this.$header.html(e.join("")), this.$header.find("th[data-field]").each(function () {
            a(this).data(d[a(this).data("field")])
        }), this.$container.off("click", ".th-inner").on("click", ".th-inner", function (c) {
            var d = a(this);
            return b.options.detailView && d.closest(".bootstrap-table")[0] !== b.$container[0] ? !1 : void(b.options.sortable && d.parent().data().sortable && b.onSort(c))
        }), this.$header.children().children().off("keypress").on("keypress", function (c) {
            if (b.options.sortable && a(this).data().sortable) {
                var d = c.keyCode || c.which;
                13 == d && b.onSort(c)
            }
        }), a(window).off("resize.bootstrap-table"), !this.options.showHeader || this.options.cardView ? (this.$header.hide(), this.$tableHeader.hide(), this.$tableLoading.css("top", 0)) : (this.$header.show(), this.$tableHeader.show(), this.$tableLoading.css("top", this.$header.outerHeight() + 1), this.getCaret(), a(window).on("resize.bootstrap-table", a.proxy(this.resetWidth, this))), this.$selectAll = this.$header.find('[name="btSelectAll"]'), this.$selectAll.off("click").on("click", function () {
            var c = a(this).prop("checked");
            b[c ? "checkAll" : "uncheckAll"](), b.updateSelected()
        })
    }, o.prototype.initFooter = function () {
        !this.options.showFooter || this.options.cardView ? this.$tableFooter.hide() : this.$tableFooter.show()
    }, o.prototype.initData = function (a, b) {
        this.data = "append" === b ? this.data.concat(a) : "prepend" === b ? [].concat(a).concat(this.data) : a || this.options.data, this.options.data = "append" === b ? this.options.data.concat(a) : "prepend" === b ? [].concat(a).concat(this.options.data) : this.data, "server" !== this.options.sidePagination && this.initSort()
    }, o.prototype.initSort = function () {
        var b = this,
            d = this.options.sortName,
            e = "desc" === this.options.sortOrder ? -1 : 1,
            f = a.inArray(this.options.sortName, this.header.fields),
            g = 0;
        return this.options.customSort !== a.noop ? void this.options.customSort.apply(this, [this.options.sortName, this.options.sortOrder]) : void(-1 !== f && (this.options.sortStable && a.each(this.data, function (a, b) {
            b.hasOwnProperty("_position") || (b._position = a)
        }), this.data.sort(function (c, g) {
            b.header.sortNames[f] && (d = b.header.sortNames[f]);
            var i = l(c, d, b.options.escape),
                j = l(g, d, b.options.escape),
                k = h(b.header, b.header.sorters[f], [i, j]);
            return void 0 !== k ? e * k : ((void 0 === i || null === i) && (i = ""), (void 0 === j || null === j) && (j = ""), b.options.sortStable && i === j && (i = c._position, j = g._position), a.isNumeric(i) && a.isNumeric(j) ? (i = parseFloat(i), j = parseFloat(j), j > i ? -1 * e : e) : i === j ? 0 : ("string" != typeof i && (i = i.toString()), -1 === i.localeCompare(j) ? -1 * e : e))
        }), void 0 !== this.options.sortClass && (clearTimeout(g), g = setTimeout(function () {
            b.$el.removeClass(b.options.sortClass);
            var a = b.$header.find(c('[data-field="%s"]', b.options.sortName).index() + 1);
            b.$el.find(c("tr td:nth-child(%s)", a)).addClass(b.options.sortClass)
        }, 250))))
    }, o.prototype.onSort = function (b) {
        var c = "keypress" === b.type ? a(b.currentTarget) : a(b.currentTarget).parent(),
            d = this.$header.find("th").eq(c.index());
        return this.$header.add(this.$header_).find("span.order").remove(), this.options.sortName === c.data("field") ? this.options.sortOrder = "asc" === this.options.sortOrder ? "desc" : "asc" : (this.options.sortName = c.data("field"), this.options.sortOrder = "asc" === c.data("order") ? "desc" : "asc"), this.trigger("sort", this.options.sortName, this.options.sortOrder), c.add(d).data("order", this.options.sortOrder), this.getCaret(), "server" === this.options.sidePagination ? void this.initServer(this.options.silentSort) : (this.initSort(), void this.initBody())
    }, o.prototype.initToolbar = function () {
        var b, d, e = this,
            f = [],
            g = 0,
            i = 0;
        this.$toolbar.find(".bs-bars").children().length && a("body").append(a(this.options.toolbar)), this.$toolbar.html(""), ("string" == typeof this.options.toolbar || "object" == typeof this.options.toolbar) && a(c('<div class="bs-bars pull-%s"></div>', this.options.toolbarAlign)).appendTo(this.$toolbar).append(a(this.options.toolbar)), f = [c('<div class="columns columns-%s btn-group pull-%s">', this.options.buttonsAlign, this.options.buttonsAlign)], "string" == typeof this.options.icons && (this.options.icons = h(null, this.options.icons)), this.options.showPaginationSwitch && f.push(c('<button class="btn' + c(" btn-%s", this.options.buttonsClass) + c(" btn-%s", this.options.iconSize) + '" type="button" name="paginationSwitch" aria-label="pagination Switch" title="%s">', this.options.formatPaginationSwitch()), c('<i class="%s %s"></i>', this.options.iconsPrefix, this.options.icons.paginationSwitchDown), "</button>"), this.options.showRefresh && f.push(c('<button class="btn' + c(" btn-%s", this.options.buttonsClass) + c(" btn-%s", this.options.iconSize) + '" type="button" name="refresh" aria-label="refresh" title="%s">', this.options.formatRefresh()), c('<i class="%s %s"></i>', this.options.iconsPrefix, this.options.icons.refresh), "</button>"), this.options.showToggle && f.push(c('<button class="btn' + c(" btn-%s", this.options.buttonsClass) + c(" btn-%s", this.options.iconSize) + '" type="button" name="toggle" aria-label="toggle" title="%s">', this.options.formatToggle()), c('<i class="%s %s"></i>', this.options.iconsPrefix, this.options.icons.toggle), "</button>"), this.options.showColumns && (f.push(c('<div class="keep-open btn-group" title="%s">', this.options.formatColumns()), '<button type="button" aria-label="columns" class="btn' + c(" btn-%s", this.options.buttonsClass) + c(" btn-%s", this.options.iconSize) + ' dropdown-toggle" data-toggle="dropdown">', c('<i class="%s %s"></i>', this.options.iconsPrefix, this.options.icons.columns), ' <span class="caret"></span>', "</button>", '<ul class="dropdown-menu" role="menu">'), a.each(this.columns, function (a, b) {
            if (!(b.radio || b.checkbox || e.options.cardView && !b.cardVisible)) {
                var d = b.visible ? ' checked="checked"' : "";
                b.switchable && (f.push(c('<li role="menuitem"><label><input type="checkbox" data-field="%s" value="%s"%s> %s</label></li>', b.field, a, d, b.title)), i++)
            }
        }), f.push("</ul>", "</div>")), f.push("</div>"), (this.showToolbar || f.length > 2) && this.$toolbar.append(f.join("")), this.options.showPaginationSwitch && this.$toolbar.find('button[name="paginationSwitch"]').off("click").on("click", a.proxy(this.togglePagination, this)), this.options.showRefresh && this.$toolbar.find('button[name="refresh"]').off("click").on("click", a.proxy(this.refresh, this)), this.options.showToggle && this.$toolbar.find('button[name="toggle"]').off("click").on("click", function () {
            e.toggleView()
        }), this.options.showColumns && (b = this.$toolbar.find(".keep-open"), i <= this.options.minimumCountColumns && b.find("input").prop("disabled", !0), b.find("li").off("click").on("click", function (a) {
            a.stopImmediatePropagation()
        }), b.find("input").off("click").on("click", function () {
            var b = a(this);
            e.toggleColumn(a(this).val(), b.prop("checked"), !1), e.trigger("column-switch", a(this).data("field"), b.prop("checked"))
        })), this.options.search && (f = [], f.push('<div class="pull-' + this.options.searchAlign + ' search">', c('<input class="form-control' + c(" input-%s", this.options.iconSize) + '" type="text" placeholder="%s">', this.options.formatSearch()), "</div>"), this.$toolbar.append(f.join("")), d = this.$toolbar.find(".search input"), d.off("keyup drop blur").on("keyup drop blur", function (b) {
            e.options.searchOnEnterKey && 13 !== b.keyCode || a.inArray(b.keyCode, [37, 38, 39, 40]) > -1 || (clearTimeout(g), g = setTimeout(function () {
                e.onSearch(b)
            }, e.options.searchTimeOut))
        }), m() && d.off("mouseup").on("mouseup", function (a) {
            clearTimeout(g), g = setTimeout(function () {
                e.onSearch(a)
            }, e.options.searchTimeOut)
        }))
    }, o.prototype.onSearch = function (b) {
        var c = a.trim(a(b.currentTarget).val());
        this.options.trimOnSearch && a(b.currentTarget).val() !== c && a(b.currentTarget).val(c), c !== this.searchText && (this.searchText = c, this.options.searchText = c, this.options.pageNumber = 1, this.initSearch(), this.updatePagination(), this.trigger("search", c))
    }, o.prototype.initSearch = function () {
        var b = this;
        if ("server" !== this.options.sidePagination) {
            if (this.options.customSearch !== a.noop) return void this.options.customSearch.apply(this, [this.searchText]);
            var c = this.searchText && (this.options.escape ? j(this.searchText) : this.searchText).toLowerCase(),
                d = a.isEmptyObject(this.filterColumns) ? null : this.filterColumns;
            this.data = d ? a.grep(this.options.data, function (b) {
                for (var c in d)
                    if (a.isArray(d[c]) && -1 === a.inArray(b[c], d[c]) || !a.isArray(d[c]) && b[c] !== d[c]) return !1;
                return !0
            }) : this.options.data, this.data = c ? a.grep(this.data, function (d, f) {
                for (var g = 0; g < b.header.fields.length; g++)
                    if (b.header.searchables[g]) {
                        var i, j = a.isNumeric(b.header.fields[g]) ? parseInt(b.header.fields[g], 10) : b.header.fields[g],
                            k = b.columns[e(b.columns, j)];
                        if ("string" == typeof j) {
                            i = d;
                            for (var l = j.split("."), m = 0; m < l.length; m++) i = i[l[m]];
                            k && k.searchFormatter && (i = h(k, b.header.formatters[g], [i, d, f], i))
                        } else i = d[j];
                        if ("string" == typeof i || "number" == typeof i)
                            if (b.options.strictSearch) {
                                if ((i + "").toLowerCase() === c) return !0
                            } else if (-1 !== (i + "").toLowerCase().indexOf(c)) return !0
                    } return !1
            }) : this.data
        }
    }, o.prototype.initPagination = function () {
        if (!this.options.pagination) return void this.$pagination.hide();
        this.$pagination.show();
        var b, d, e, f, g, h, i, j, k, l = this,
            m = [],
            n = !1,
            o = this.getData(),
            p = this.options.pageList;
        if ("server" !== this.options.sidePagination && (this.options.totalRows = o.length), this.totalPages = 0, this.options.totalRows) {
            if (this.options.pageSize === this.options.formatAllRows()) this.options.pageSize = this.options.totalRows, n = !0;
            else if (this.options.pageSize === this.options.totalRows) {
                var q = "string" == typeof this.options.pageList ? this.options.pageList.replace("[", "").replace("]", "").replace(/ /g, "").toLowerCase().split(",") : this.options.pageList;
                a.inArray(this.options.formatAllRows().toLowerCase(), q) > -1 && (n = !0)
            }
            this.totalPages = ~~((this.options.totalRows - 1) / this.options.pageSize) + 1, this.options.totalPages = this.totalPages
        }
        if (this.totalPages > 0 && this.options.pageNumber > this.totalPages && (this.options.pageNumber = this.totalPages), this.pageFrom = (this.options.pageNumber - 1) * this.options.pageSize + 1, this.pageTo = this.options.pageNumber * this.options.pageSize, this.pageTo > this.options.totalRows && (this.pageTo = this.options.totalRows), m.push('<div class="pull-' + this.options.paginationDetailHAlign + ' pagination-detail">', '<span class="pagination-info">', this.options.onlyInfoPagination ? this.options.formatDetailPagination(this.options.totalRows) : this.options.formatShowingRows(this.pageFrom, this.pageTo, this.options.totalRows), "</span>"), !this.options.onlyInfoPagination) {
            m.push('<span class="page-list">');
            var r = [c('<span class="btn-group %s">', "top" === this.options.paginationVAlign || "both" === this.options.paginationVAlign ? "dropdown" : "dropup"), '<button type="button" class="btn' + c(" btn-%s", this.options.buttonsClass) + c(" btn-%s", this.options.iconSize) + ' dropdown-toggle" data-toggle="dropdown">', '<span class="page-size">', n ? this.options.formatAllRows() : this.options.pageSize, "</span>", ' <span class="caret"></span>', "</button>", '<ul class="dropdown-menu" role="menu">'];
            if ("string" == typeof this.options.pageList) {
                var s = this.options.pageList.replace("[", "").replace("]", "").replace(/ /g, "").split(",");
                p = [], a.each(s, function (a, b) {
                    p.push(b.toUpperCase() === l.options.formatAllRows().toUpperCase() ? l.options.formatAllRows() : +b)
                })
            }
            for (a.each(p, function (a, b) {
                    if (!l.options.smartDisplay || 0 === a || p[a - 1] < l.options.totalRows) {
                        var d;
                        d = n ? b === l.options.formatAllRows() ? ' class="active"' : "" : b === l.options.pageSize ? ' class="active"' : "", r.push(c('<li role="menuitem"%s><a href="#">%s</a></li>', d, b))
                    }
                }), r.push("</ul></span>"), m.push(this.options.formatRecordsPerPage(r.join(""))), m.push("</span>"), m.push("</div>", '<div class="pull-' + this.options.paginationHAlign + ' pagination">', '<ul class="pagination' + c(" pagination-%s", this.options.iconSize) + '">', '<li class="page-pre"><a href="#">' + this.options.paginationPreText + "</a></li>"), this.totalPages < 5 ? (d = 1, e = this.totalPages) : (d = this.options.pageNumber - 2, e = d + 4, 1 > d && (d = 1, e = 5), e > this.totalPages && (e = this.totalPages, d = e - 4)), this.totalPages >= 6 && (this.options.pageNumber >= 3 && (m.push('<li class="page-first' + (1 === this.options.pageNumber ? " active" : "") + '">', '<a href="#">', 1, "</a>", "</li>"), d++), this.options.pageNumber >= 4 && (4 == this.options.pageNumber || 6 == this.totalPages || 7 == this.totalPages ? d-- : m.push('<li class="page-first-separator disabled">', '<a href="#">...</a>', "</li>"), e--)), this.totalPages >= 7 && this.options.pageNumber >= this.totalPages - 2 && d--, 6 == this.totalPages ? this.options.pageNumber >= this.totalPages - 2 && e++ : this.totalPages >= 7 && (7 == this.totalPages || this.options.pageNumber >= this.totalPages - 3) && e++, b = d; e >= b; b++) m.push('<li class="page-number' + (b === this.options.pageNumber ? " active" : "") + '">', '<a href="#">', b, "</a>", "</li>");
            this.totalPages >= 8 && this.options.pageNumber <= this.totalPages - 4 && m.push('<li class="page-last-separator disabled">', '<a href="#">...</a>', "</li>"), this.totalPages >= 6 && this.options.pageNumber <= this.totalPages - 3 && m.push('<li class="page-last' + (this.totalPages === this.options.pageNumber ? " active" : "") + '">', '<a href="#">', this.totalPages, "</a>", "</li>"), m.push('<li class="page-next"><a href="#">' + this.options.paginationNextText + "</a></li>", "</ul>", "</div>")
        }
        this.$pagination.html(m.join("")), this.options.onlyInfoPagination || (f = this.$pagination.find(".page-list a"), g = this.$pagination.find(".page-first"), h = this.$pagination.find(".page-pre"), i = this.$pagination.find(".page-next"), j = this.$pagination.find(".page-last"), k = this.$pagination.find(".page-number"), this.options.smartDisplay && (this.totalPages <= 1 && this.$pagination.find("div.pagination").hide(), (p.length < 2 || this.options.totalRows <= p[0]) && this.$pagination.find("span.page-list").hide(), this.$pagination[this.getData().length ? "show" : "hide"]()), this.options.paginationLoop || (1 === this.options.pageNumber && h.addClass("disabled"), this.options.pageNumber === this.totalPages && i.addClass("disabled")), n && (this.options.pageSize = this.options.formatAllRows()), f.off("click").on("click", a.proxy(this.onPageListChange, this)), g.off("click").on("click", a.proxy(this.onPageFirst, this)), h.off("click").on("click", a.proxy(this.onPagePre, this)), i.off("click").on("click", a.proxy(this.onPageNext, this)), j.off("click").on("click", a.proxy(this.onPageLast, this)), k.off("click").on("click", a.proxy(this.onPageNumber, this)))
    }, o.prototype.updatePagination = function (b) {
        b && a(b.currentTarget).hasClass("disabled") || (this.options.maintainSelected || this.resetRows(), this.initPagination(), "server" === this.options.sidePagination ? this.initServer() : this.initBody(), this.trigger("page-change", this.options.pageNumber, this.options.pageSize))
    }, o.prototype.onPageListChange = function (b) {
        var c = a(b.currentTarget);
        return c.parent().addClass("active").siblings().removeClass("active"), this.options.pageSize = c.text().toUpperCase() === this.options.formatAllRows().toUpperCase() ? this.options.formatAllRows() : +c.text(), this.$toolbar.find(".page-size").text(this.options.pageSize), this.updatePagination(b), !1
    }, o.prototype.onPageFirst = function (a) {
        return this.options.pageNumber = 1, this.updatePagination(a), !1
    }, o.prototype.onPagePre = function (a) {
        return this.options.pageNumber - 1 === 0 ? this.options.pageNumber = this.options.totalPages : this.options.pageNumber--, this.updatePagination(a), !1
    }, o.prototype.onPageNext = function (a) {
        return this.options.pageNumber + 1 > this.options.totalPages ? this.options.pageNumber = 1 : this.options.pageNumber++, this.updatePagination(a), !1
    }, o.prototype.onPageLast = function (a) {
        return this.options.pageNumber = this.totalPages, this.updatePagination(a), !1
    }, o.prototype.onPageNumber = function (b) {
        return this.options.pageNumber !== +a(b.currentTarget).text() ? (this.options.pageNumber = +a(b.currentTarget).text(), this.updatePagination(b), !1) : void 0
    }, o.prototype.initRow = function (b, e) {
        var f, g = this,
            i = [],
            k = {},
            m = [],
            n = "",
            o = {},
            p = [];
        if (!(a.inArray(b, this.hiddenRows) > -1)) {
            if (k = h(this.options, this.options.rowStyle, [b, e], k), k && k.css)
                for (f in k.css) m.push(f + ": " + k.css[f]);
            if (o = h(this.options, this.options.rowAttributes, [b, e], o))
                for (f in o) p.push(c('%s="%s"', f, j(o[f])));
            return b._data && !a.isEmptyObject(b._data) && a.each(b._data, function (a, b) {
                "index" !== a && (n += c(' data-%s="%s"', a, b))
            }), i.push("<tr", c(" %s", p.join(" ")), c(' id="%s"', a.isArray(b) ? void 0 : b._id), c(' class="%s"', k.classes || (a.isArray(b) ? void 0 : b._class)), c(' data-index="%s"', e), c(' data-uniqueid="%s"', b[this.options.uniqueId]), c("%s", n), ">"), this.options.cardView && i.push(c('<td colspan="%s"><div class="card-views">', this.header.fields.length)), !this.options.cardView && this.options.detailView && i.push("<td>", '<a class="detail-icon" href="#">', c('<i class="%s %s"></i>', this.options.iconsPrefix, this.options.icons.detailOpen), "</a>", "</td>"), a.each(this.header.fields, function (f, n) {
                var o = "",
                    p = l(b, n, g.options.escape),
                    q = "",
                    r = "",
                    s = {},
                    t = "",
                    u = g.header.classes[f],
                    v = "",
                    w = "",
                    x = "",
                    y = "",
                    z = g.columns[f];
                if (!(g.fromHtml && "undefined" == typeof p || !z.visible || g.options.cardView && !z.cardVisible)) {
                    if (z.escape && (p = j(p)), k = c('style="%s"', m.concat(g.header.styles[f]).join("; ")), b["_" + n + "_id"] && (t = c(' id="%s"', b["_" + n + "_id"])), b["_" + n + "_class"] && (u = c(' class="%s"', b["_" + n + "_class"])), b["_" + n + "_rowspan"] && (w = c(' rowspan="%s"', b["_" + n + "_rowspan"])), b["_" + n + "_colspan"] && (x = c(' colspan="%s"', b["_" + n + "_colspan"])), b["_" + n + "_title"] && (y = c(' title="%s"', b["_" + n + "_title"])), s = h(g.header, g.header.cellStyles[f], [p, b, e, n], s), s.classes && (u = c(' class="%s"', s.classes)), s.css) {
                        var A = [];
                        for (var B in s.css) A.push(B + ": " + s.css[B]);
                        k = c('style="%s"', A.concat(g.header.styles[f]).join("; "))
                    }
                    q = h(z, g.header.formatters[f], [p, b, e], p), b["_" + n + "_data"] && !a.isEmptyObject(b["_" + n + "_data"]) && a.each(b["_" + n + "_data"], function (a, b) {
                        "index" !== a && (v += c(' data-%s="%s"', a, b))
                    }), z.checkbox || z.radio ? (r = z.checkbox ? "checkbox" : r, r = z.radio ? "radio" : r, o = [c(g.options.cardView ? '<div class="card-view %s">' : '<td class="bs-checkbox %s">', z["class"] || ""), "<input" + c(' data-index="%s"', e) + c(' name="%s"', g.options.selectItemName) + c(' type="%s"', r) + c(' value="%s"', b[g.options.idField]) + c(' checked="%s"', q === !0 || p || q && q.checked ? "checked" : void 0) + c(' disabled="%s"', !z.checkboxEnabled || q && q.disabled ? "disabled" : void 0) + " />", g.header.formatters[f] && "string" == typeof q ? q : "", g.options.cardView ? "</div>" : "</td>"].join(""), b[g.header.stateField] = q === !0 || q && q.checked) : (q = "undefined" == typeof q || null === q ? g.options.undefinedText : q, o = g.options.cardView ? ['<div class="card-view">', g.options.showHeader ? c('<span class="title" %s>%s</span>', k, d(g.columns, "field", "title", n)) : "", c('<span class="value">%s</span>', q), "</div>"].join("") : [c("<td%s %s %s %s %s %s %s>", t, u, k, v, w, x, y), q, "</td>"].join(""), g.options.cardView && g.options.smartDisplay && "" === q && (o = '<div class="card-view"></div>')), i.push(o)
                }
            }), this.options.cardView && i.push("</div></td>"), i.push("</tr>"), i.join(" ")
        }
    }, o.prototype.initBody = function (b) {
        var d = this,
            f = this.getData();
        this.trigger("pre-body", f), this.$body = this.$el.find(">tbody"), this.$body.length || (this.$body = a("<tbody></tbody>").appendTo(this.$el)), this.options.pagination && "server" !== this.options.sidePagination || (this.pageFrom = 1, this.pageTo = f.length);
        for (var g, i = a(document.createDocumentFragment()), j = this.pageFrom - 1; j < this.pageTo; j++) {
            var k = f[j],
                m = this.initRow(k, j, f, i);
            g = g || !!m, m && m !== !0 && i.append(m)
        }
        g || i.append('<tr class="no-records-found">' + c('<td colspan="%s">%s</td>', this.$header.find("th").length, this.options.formatNoMatches()) + "</tr>"), this.$body.html(i), b || this.scrollTo(0), this.$body.find("> tr[data-index] > td").off("click dblclick").on("click dblclick", function (b) {
            var f = a(this),
                g = f.parent(),
                h = d.data[g.data("index")],
                i = f[0].cellIndex,
                j = d.getVisibleFields(),
                k = j[d.options.detailView && !d.options.cardView ? i - 1 : i],
                m = d.columns[e(d.columns, k)],
                n = l(h, k, d.options.escape);
            if (!f.find(".detail-icon").length && (d.trigger("click" === b.type ? "click-cell" : "dbl-click-cell", k, n, h, f), d.trigger("click" === b.type ? "click-row" : "dbl-click-row", h, g, k), "click" === b.type && d.options.clickToSelect && m.clickToSelect)) {
                var o = g.find(c('[name="%s"]', d.options.selectItemName));
                o.length && o[0].click()
            }
        }), this.$body.find("> tr[data-index] > td > .detail-icon").off("click").on("click", function () {
            var b = a(this),
                e = b.parent().parent(),
                g = e.data("index"),
                i = f[g];
            if (e.next().is("tr.detail-view")) b.find("i").attr("class", c("%s %s", d.options.iconsPrefix, d.options.icons.detailOpen)), d.trigger("collapse-row", g, i), e.next().remove();
            else {
                b.find("i").attr("class", c("%s %s", d.options.iconsPrefix, d.options.icons.detailClose)), e.after(c('<tr class="detail-view"><td colspan="%s"></td></tr>', e.find("td").length));
                var j = e.next().find("td"),
                    k = h(d.options, d.options.detailFormatter, [g, i, j], "");
                1 === j.length && j.append(k), d.trigger("expand-row", g, i, j)
            }
            return d.resetView(), !1
        }), this.$selectItem = this.$body.find(c('[name="%s"]', this.options.selectItemName)), this.$selectItem.off("click").on("click", function (b) {
            b.stopImmediatePropagation();
            var c = a(this),
                e = c.prop("checked"),
                f = d.data[c.data("index")];
            d.options.maintainSelected && a(this).is(":radio") && a.each(d.options.data, function (a, b) {
                b[d.header.stateField] = !1
            }), f[d.header.stateField] = e, d.options.singleSelect && (d.$selectItem.not(this).each(function () {
                d.data[a(this).data("index")][d.header.stateField] = !1
            }), d.$selectItem.filter(":checked").not(this).prop("checked", !1)), d.updateSelected(), d.trigger(e ? "check" : "uncheck", f, c)
        }), a.each(this.header.events, function (b, c) {
            if (c) {
                "string" == typeof c && (c = h(null, c));
                var e = d.header.fields[b],
                    f = a.inArray(e, d.getVisibleFields());
                d.options.detailView && !d.options.cardView && (f += 1);
                for (var g in c) d.$body.find(">tr:not(.no-records-found)").each(function () {
                    var b = a(this),
                        h = b.find(d.options.cardView ? ".card-view" : "td").eq(f),
                        i = g.indexOf(" "),
                        j = g.substring(0, i),
                        k = g.substring(i + 1),
                        l = c[g];
                    h.find(k).off(j).on(j, function (a) {
                        var c = b.data("index"),
                            f = d.data[c],
                            g = f[e];
                        l.apply(this, [a, g, f, c])
                    })
                })
            }
        }), this.updateSelected(), this.resetView(), this.trigger("post-body", f)
    }, o.prototype.initServer = function (b, c, d) {
        var e, f = this,
            g = {},
            i = {
                searchText: this.searchText,
                sortName: this.options.sortName,
                sortOrder: this.options.sortOrder
            };
        this.options.pagination && (i.pageSize = this.options.pageSize === this.options.formatAllRows() ? this.options.totalRows : this.options.pageSize, i.pageNumber = this.options.pageNumber), (d || this.options.url || this.options.ajax) && ("limit" === this.options.queryParamsType && (i = {
            search: i.searchText,
            sort: i.sortName,
            order: i.sortOrder
        }, this.options.pagination && (i.offset = this.options.pageSize === this.options.formatAllRows() ? 0 : this.options.pageSize * (this.options.pageNumber - 1), i.limit = this.options.pageSize === this.options.formatAllRows() ? this.options.totalRows : this.options.pageSize)), a.isEmptyObject(this.filterColumnsPartial) || (i.filter = JSON.stringify(this.filterColumnsPartial, null)), g = h(this.options, this.options.queryParams, [i], g), a.extend(g, c || {}), g !== !1 && (b || this.$tableLoading.show(), e = a.extend({}, h(null, this.options.ajaxOptions), {
            type: this.options.method,
            url: d || this.options.url,
            data: "application/json" === this.options.contentType && "post" === this.options.method ? JSON.stringify(g) : g,
            cache: this.options.cache,
            contentType: this.options.contentType,
            dataType: this.options.dataType,
            success: function (a) {
                a = h(f.options, f.options.responseHandler, [a], a), f.load(a), f.trigger("load-success", a), b || f.$tableLoading.hide()
            },
            error: function (a) {
                f.trigger("load-error", a.status, a), b || f.$tableLoading.hide()
            }
        }), this.options.ajax ? h(this, this.options.ajax, [e], null) : (this._xhr && 4 !== this._xhr.readyState && this._xhr.abort(), this._xhr = a.ajax(e))))
    }, o.prototype.initSearchText = function () {
        if (this.options.search && "" !== this.options.searchText) {
            var a = this.$toolbar.find(".search input");
            a.val(this.options.searchText), this.onSearch({
                currentTarget: a
            })
        }
    }, o.prototype.getCaret = function () {
        var b = this;
        a.each(this.$header.find("th"), function (c, d) {
            a(d).find(".sortable").removeClass("desc asc").addClass(a(d).data("field") === b.options.sortName ? b.options.sortOrder : "both")
        })
    }, o.prototype.updateSelected = function () {
        var b = this.$selectItem.filter(":enabled").length && this.$selectItem.filter(":enabled").length === this.$selectItem.filter(":enabled").filter(":checked").length;
        this.$selectAll.add(this.$selectAll_).prop("checked", b), this.$selectItem.each(function () {
            a(this).closest("tr")[a(this).prop("checked") ? "addClass" : "removeClass"]("selected")
        })
    }, o.prototype.updateRows = function () {
        var b = this;
        this.$selectItem.each(function () {
            b.data[a(this).data("index")][b.header.stateField] = a(this).prop("checked")
        })
    }, o.prototype.resetRows = function () {
        var b = this;
        a.each(this.data, function (a, c) {
            b.$selectAll.prop("checked", !1), b.$selectItem.prop("checked", !1), b.header.stateField && (c[b.header.stateField] = !1)
        }), this.initHiddenRows()
    }, o.prototype.trigger = function (b) {
        var c = Array.prototype.slice.call(arguments, 1);
        b += ".bs.table", this.options[o.EVENTS[b]].apply(this.options, c), this.$el.trigger(a.Event(b), c), this.options.onAll(b, c), this.$el.trigger(a.Event("all.bs.table"), [b, c])
    }, o.prototype.resetHeader = function () {
        clearTimeout(this.timeoutId_), this.timeoutId_ = setTimeout(a.proxy(this.fitHeader, this), this.$el.is(":hidden") ? 100 : 0)
    }, o.prototype.fitHeader = function () {
        var b, d, e, f, h = this;
        if (h.$el.is(":hidden")) return void(h.timeoutId_ = setTimeout(a.proxy(h.fitHeader, h), 100));
        if (b = this.$tableBody.get(0), d = b.scrollWidth > b.clientWidth && b.scrollHeight > b.clientHeight + this.$header.outerHeight() ? g() : 0, this.$el.css("margin-top", -this.$header.outerHeight()), e = a(":focus"), e.length > 0) {
            var i = e.parents("th");
            if (i.length > 0) {
                var j = i.attr("data-field");
                if (void 0 !== j) {
                    var k = this.$header.find("[data-field='" + j + "']");
                    k.length > 0 && k.find(":input").addClass("focus-temp")
                }
            }
        }
        this.$header_ = this.$header.clone(!0, !0), this.$selectAll_ = this.$header_.find('[name="btSelectAll"]'), this.$tableHeader.css({
            "margin-right": d
        }).find("table").css("width", this.$el.outerWidth()).html("").attr("class", this.$el.attr("class")).append(this.$header_), f = a(".focus-temp:visible:eq(0)"), f.length > 0 && (f.focus(), this.$header.find(".focus-temp").removeClass("focus-temp")), this.$header.find("th[data-field]").each(function () {
            h.$header_.find(c('th[data-field="%s"]', a(this).data("field"))).data(a(this).data())
        });
        var l = this.getVisibleFields(),
            m = this.$header_.find("th");
        this.$body.find(">tr:first-child:not(.no-records-found) > *").each(function (b) {
            var d = a(this),
                e = b;
            h.options.detailView && !h.options.cardView && (0 === b && h.$header_.find("th.detail").find(".fht-cell").width(d.innerWidth()), e = b - 1);
            var f = h.$header_.find(c('th[data-field="%s"]', l[e]));
            f.length > 1 && (f = a(m[d[0].cellIndex])), f.find(".fht-cell").width(d.innerWidth())
        }), this.$tableBody.off("scroll").on("scroll", function () {
            h.$tableHeader.scrollLeft(a(this).scrollLeft()), h.options.showFooter && !h.options.cardView && h.$tableFooter.scrollLeft(a(this).scrollLeft())
        }), h.trigger("post-header")
    }, o.prototype.resetFooter = function () {
        var b = this,
            d = b.getData(),
            e = [];
        this.options.showFooter && !this.options.cardView && (!this.options.cardView && this.options.detailView && e.push('<td><div class="th-inner">&nbsp;</div><div class="fht-cell"></div></td>'), a.each(this.columns, function (a, f) {
            var g, i = "",
                j = "",
                k = [],
                l = {},
                m = c(' class="%s"', f["class"]);
            if (f.visible && (!b.options.cardView || f.cardVisible)) {
                if (i = c("text-align: %s; ", f.falign ? f.falign : f.align), j = c("vertical-align: %s; ", f.valign), l = h(null, b.options.footerStyle), l && l.css)
                    for (g in l.css) k.push(g + ": " + l.css[g]);
                e.push("<td", m, c(' style="%s"', i + j + k.concat().join("; ")), ">"), e.push('<div class="th-inner">'), e.push(h(f, f.footerFormatter, [d], "&nbsp;") || "&nbsp;"), e.push("</div>"), e.push('<div class="fht-cell"></div>'), e.push("</div>"), e.push("</td>")
            }
        }), this.$tableFooter.find("tr").html(e.join("")), this.$tableFooter.show(), clearTimeout(this.timeoutFooter_), this.timeoutFooter_ = setTimeout(a.proxy(this.fitFooter, this), this.$el.is(":hidden") ? 100 : 0))
    }, o.prototype.fitFooter = function () {
        var b, c, d;
        return clearTimeout(this.timeoutFooter_), this.$el.is(":hidden") ? void(this.timeoutFooter_ = setTimeout(a.proxy(this.fitFooter, this), 100)) : (c = this.$el.css("width"), d = c > this.$tableBody.width() ? g() : 0, this.$tableFooter.css({
            "margin-right": d
        }).find("table").css("width", c).attr("class", this.$el.attr("class")), b = this.$tableFooter.find("td"), void this.$body.find(">tr:first-child:not(.no-records-found) > *").each(function (c) {
            var d = a(this);
            b.eq(c).find(".fht-cell").width(d.innerWidth())
        }))
    }, o.prototype.toggleColumn = function (a, b, d) {
        if (-1 !== a && (this.columns[a].visible = b, this.initHeader(), this.initSearch(), this.initPagination(), this.initBody(), this.options.showColumns)) {
            var e = this.$toolbar.find(".keep-open input").prop("disabled", !1);
            d && e.filter(c('[value="%s"]', a)).prop("checked", b), e.filter(":checked").length <= this.options.minimumCountColumns && e.filter(":checked").prop("disabled", !0)
        }
    }, o.prototype.getVisibleFields = function () {
        var b = this,
            c = [];
        return a.each(this.header.fields, function (a, d) {
            var f = b.columns[e(b.columns, d)];
            f.visible && c.push(d)
        }), c
    }, o.prototype.resetView = function (a) {
        var b = 0;
        if (a && a.height && (this.options.height = a.height), this.$selectAll.prop("checked", this.$selectItem.length > 0 && this.$selectItem.length === this.$selectItem.filter(":checked").length), this.options.height) {
            var c = this.$toolbar.outerHeight(!0),
                d = this.$pagination.outerHeight(!0),
                e = this.options.height - c - d;
            this.$tableContainer.css("height", e + "px")
        }
        return this.options.cardView ? (this.$el.css("margin-top", "0"), this.$tableContainer.css("padding-bottom", "0"), void this.$tableFooter.hide()) : (this.options.showHeader && this.options.height ? (this.$tableHeader.show(), this.resetHeader(), b += this.$header.outerHeight()) : (this.$tableHeader.hide(), this.trigger("post-header")), this.options.showFooter && (this.resetFooter(), this.options.height && (b += this.$tableFooter.outerHeight() + 1)), this.getCaret(), this.$tableContainer.css("padding-bottom", b + "px"), void this.trigger("reset-view"))
    }, o.prototype.getData = function (b) {
        return !this.searchText && a.isEmptyObject(this.filterColumns) && a.isEmptyObject(this.filterColumnsPartial) ? b ? this.options.data.slice(this.pageFrom - 1, this.pageTo) : this.options.data : b ? this.data.slice(this.pageFrom - 1, this.pageTo) : this.data
    }, o.prototype.load = function (b) {
        var c = !1;
        "server" === this.options.sidePagination ? (this.options.totalRows = b[this.options.totalField], c = b.fixedScroll, b = b[this.options.dataField]) : a.isArray(b) || (c = b.fixedScroll, b = b.data), this.initData(b), this.initSearch(), this.initPagination(), this.initBody(c)
    }, o.prototype.append = function (a) {
        this.initData(a, "append"), this.initSearch(), this.initPagination(), this.initSort(), this.initBody(!0)
    }, o.prototype.prepend = function (a) {
        this.initData(a, "prepend"), this.initSearch(), this.initPagination(), this.initSort(), this.initBody(!0)
    }, o.prototype.remove = function (b) {
        var c, d, e = this.options.data.length;
        if (b.hasOwnProperty("field") && b.hasOwnProperty("values")) {
            for (c = e - 1; c >= 0; c--) d = this.options.data[c], d.hasOwnProperty(b.field) && -1 !== a.inArray(d[b.field], b.values) && (this.options.data.splice(c, 1), "server" === this.options.sidePagination && (this.options.totalRows -= 1));
            e !== this.options.data.length && (this.initSearch(), this.initPagination(), this.initSort(), this.initBody(!0))
        }
    }, o.prototype.removeAll = function () {
        this.options.data.length > 0 && (this.options.data.splice(0, this.options.data.length), this.initSearch(), this.initPagination(), this.initBody(!0))
    }, o.prototype.getRowByUniqueId = function (a) {
        var b, c, d, e = this.options.uniqueId,
            f = this.options.data.length,
            g = null;
        for (b = f - 1; b >= 0; b--) {
            if (c = this.options.data[b], c.hasOwnProperty(e)) d = c[e];
            else {
                if (!c._data.hasOwnProperty(e)) continue;
                d = c._data[e]
            }
            if ("string" == typeof d ? a = a.toString() : "number" == typeof d && (Number(d) === d && d % 1 === 0 ? a = parseInt(a) : d === Number(d) && 0 !== d && (a = parseFloat(a))), d === a) {
                g = c;
                break
            }
        }
        return g
    }, o.prototype.removeByUniqueId = function (a) {
        var b = this.options.data.length,
            c = this.getRowByUniqueId(a);
        c && this.options.data.splice(this.options.data.indexOf(c), 1), b !== this.options.data.length && (this.initSearch(), this.initPagination(), this.initBody(!0))
    }, o.prototype.updateByUniqueId = function (b) {
        var c = this,
            d = a.isArray(b) ? b : [b];
        a.each(d, function (b, d) {
            var e;
            d.hasOwnProperty("id") && d.hasOwnProperty("row") && (e = a.inArray(c.getRowByUniqueId(d.id), c.options.data), -1 !== e && a.extend(c.options.data[e], d.row))
        }), this.initSearch(), this.initPagination(), this.initSort(), this.initBody(!0)
    }, o.prototype.insertRow = function (a) {
        a.hasOwnProperty("index") && a.hasOwnProperty("row") && (this.data.splice(a.index, 0, a.row), this.initSearch(), this.initPagination(), this.initSort(), this.initBody(!0))
    }, o.prototype.updateRow = function (b) {
        var c = this,
            d = a.isArray(b) ? b : [b];
        a.each(d, function (b, d) {
            d.hasOwnProperty("index") && d.hasOwnProperty("row") && a.extend(c.options.data[d.index], d.row)
        }), this.initSearch(), this.initPagination(), this.initSort(), this.initBody(!0)
    }, o.prototype.initHiddenRows = function () {
        this.hiddenRows = []
    }, o.prototype.showRow = function (a) {
        this.toggleRow(a, !0)
    }, o.prototype.hideRow = function (a) {
        this.toggleRow(a, !1)
    }, o.prototype.toggleRow = function (b, c) {
        var d, e;
        b.hasOwnProperty("index") ? d = this.getData()[b.index] : b.hasOwnProperty("uniqueId") && (d = this.getRowByUniqueId(b.uniqueId)), d && (e = a.inArray(d, this.hiddenRows), c || -1 !== e ? c && e > -1 && this.hiddenRows.splice(e, 1) : this.hiddenRows.push(d), this.initBody(!0))
    }, o.prototype.getHiddenRows = function () {
        var b = this,
            c = this.getData(),
            d = [];
        return a.each(c, function (c, e) {
            a.inArray(e, b.hiddenRows) > -1 && d.push(e)
        }), this.hiddenRows = d, d
    }, o.prototype.mergeCells = function (b) {
        var c, d, e, f = b.index,
            g = a.inArray(b.field, this.getVisibleFields()),
            h = b.rowspan || 1,
            i = b.colspan || 1,
            j = this.$body.find(">tr");
        if (this.options.detailView && !this.options.cardView && (g += 1), e = j.eq(f).find(">td").eq(g), !(0 > f || 0 > g || f >= this.data.length)) {
            for (c = f; f + h > c; c++)
                for (d = g; g + i > d; d++) j.eq(c).find(">td").eq(d).hide();
            e.attr("rowspan", h).attr("colspan", i).show()
        }
    }, o.prototype.updateCell = function (a) {
        a.hasOwnProperty("index") && a.hasOwnProperty("field") && a.hasOwnProperty("value") && (this.data[a.index][a.field] = a.value, a.reinit !== !1 && (this.initSort(), this.initBody(!0)))
    }, o.prototype.getOptions = function () {
        return this.options
    }, o.prototype.getSelections = function () {
        var b = this;
        return a.grep(this.options.data, function (a) {
            return a[b.header.stateField] === !0
        })
    }, o.prototype.getAllSelections = function () {
        var b = this;
        return a.grep(this.options.data, function (a) {
            return a[b.header.stateField]
        })
    }, o.prototype.checkAll = function () {
        this.checkAll_(!0)
    }, o.prototype.uncheckAll = function () {
        this.checkAll_(!1)
    }, o.prototype.checkInvert = function () {
        var b = this,
            c = b.$selectItem.filter(":enabled"),
            d = c.filter(":checked");
        c.each(function () {
            a(this).prop("checked", !a(this).prop("checked"))
        }), b.updateRows(), b.updateSelected(), b.trigger("uncheck-some", d), d = b.getSelections(), b.trigger("check-some", d)
    }, o.prototype.checkAll_ = function (a) {
        var b;
        a || (b = this.getSelections()), this.$selectAll.add(this.$selectAll_).prop("checked", a), this.$selectItem.filter(":enabled").prop("checked", a), this.updateRows(), a && (b = this.getSelections()), this.trigger(a ? "check-all" : "uncheck-all", b)
    }, o.prototype.check = function (a) {
        this.check_(!0, a)
    }, o.prototype.uncheck = function (a) {
        this.check_(!1, a)
    }, o.prototype.check_ = function (a, b) {
        var d = this.$selectItem.filter(c('[data-index="%s"]', b)).prop("checked", a);
        this.data[b][this.header.stateField] = a, this.updateSelected(), this.trigger(a ? "check" : "uncheck", this.data[b], d)
    }, o.prototype.checkBy = function (a) {
        this.checkBy_(!0, a)
    }, o.prototype.uncheckBy = function (a) {
        this.checkBy_(!1, a)
    }, o.prototype.checkBy_ = function (b, d) {
        if (d.hasOwnProperty("field") && d.hasOwnProperty("values")) {
            var e = this,
                f = [];
            a.each(this.options.data, function (g, h) {
                if (!h.hasOwnProperty(d.field)) return !1;
                if (-1 !== a.inArray(h[d.field], d.values)) {
                    var i = e.$selectItem.filter(":enabled").filter(c('[data-index="%s"]', g)).prop("checked", b);
                    h[e.header.stateField] = b, f.push(h), e.trigger(b ? "check" : "uncheck", h, i)
                }
            }), this.updateSelected(), this.trigger(b ? "check-some" : "uncheck-some", f)
        }
    }, o.prototype.destroy = function () {
        this.$el.insertBefore(this.$container), a(this.options.toolbar).insertBefore(this.$el), this.$container.next().remove(), this.$container.remove(), this.$el.html(this.$el_.html()).css("margin-top", "0").attr("class", this.$el_.attr("class") || "")
    }, o.prototype.showLoading = function () {
        this.$tableLoading.show()
    }, o.prototype.hideLoading = function () {
        this.$tableLoading.hide()
    }, o.prototype.togglePagination = function () {
        this.options.pagination = !this.options.pagination;
        var a = this.$toolbar.find('button[name="paginationSwitch"] i');
        this.options.pagination ? a.attr("class", this.options.iconsPrefix + " " + this.options.icons.paginationSwitchDown) : a.attr("class", this.options.iconsPrefix + " " + this.options.icons.paginationSwitchUp), this.updatePagination()
    }, o.prototype.refresh = function (a) {
        a && a.url && (this.options.url = a.url), a && a.pageNumber && (this.options.pageNumber = a.pageNumber), a && a.pageSize && (this.options.pageSize = a.pageSize), this.initServer(a && a.silent, a && a.query, a && a.url), this.trigger("refresh", a)
    }, o.prototype.resetWidth = function () {
        this.options.showHeader && this.options.height && this.fitHeader(), this.options.showFooter && this.fitFooter()
    }, o.prototype.showColumn = function (a) {
        this.toggleColumn(e(this.columns, a), !0, !0)
    }, o.prototype.hideColumn = function (a) {
        this.toggleColumn(e(this.columns, a), !1, !0)
    }, o.prototype.getHiddenColumns = function () {
        return a.grep(this.columns, function (a) {
            return !a.visible
        })
    }, o.prototype.getVisibleColumns = function () {
        return a.grep(this.columns, function (a) {
            return a.visible
        })
    }, o.prototype.toggleAllColumns = function (b) {
        if (a.each(this.columns, function (a) {
                this.columns[a].visible = b
            }), this.initHeader(), this.initSearch(), this.initPagination(), this.initBody(), this.options.showColumns) {
            var c = this.$toolbar.find(".keep-open input").prop("disabled", !1);
            c.filter(":checked").length <= this.options.minimumCountColumns && c.filter(":checked").prop("disabled", !0)
        }
    }, o.prototype.showAllColumns = function () {
        this.toggleAllColumns(!0)
    }, o.prototype.hideAllColumns = function () {
        this.toggleAllColumns(!1)
    }, o.prototype.filterBy = function (b) {
        this.filterColumns = a.isEmptyObject(b) ? {} : b, this.options.pageNumber = 1, this.initSearch(), this.updatePagination()
    }, o.prototype.scrollTo = function (a) {
        return "string" == typeof a && (a = "bottom" === a ? this.$tableBody[0].scrollHeight : 0), "number" == typeof a && this.$tableBody.scrollTop(a), "undefined" == typeof a ? this.$tableBody.scrollTop() : void 0
    }, o.prototype.getScrollPosition = function () {
        return this.scrollTo()
    }, o.prototype.selectPage = function (a) {
        a > 0 && a <= this.options.totalPages && (this.options.pageNumber = a, this.updatePagination())
    }, o.prototype.prevPage = function () {
        this.options.pageNumber > 1 && (this.options.pageNumber--, this.updatePagination())
    }, o.prototype.nextPage = function () {
        this.options.pageNumber < this.options.totalPages && (this.options.pageNumber++, this.updatePagination())
    }, o.prototype.toggleView = function () {
        this.options.cardView = !this.options.cardView, this.initHeader(), this.initBody(), this.trigger("toggle", this.options.cardView)
    }, o.prototype.refreshOptions = function (b) {
        i(this.options, b, !0) || (this.options = a.extend(this.options, b), this.trigger("refresh-options", this.options), this.destroy(), this.init())
    }, o.prototype.resetSearch = function (a) {
        var b = this.$toolbar.find(".search input");
        b.val(a || ""), this.onSearch({
            currentTarget: b
        })
    }, o.prototype.expandRow_ = function (a, b) {
        var d = this.$body.find(c('> tr[data-index="%s"]', b));
        d.next().is("tr.detail-view") === (a ? !1 : !0) && d.find("> td > .detail-icon").click()
    }, o.prototype.expandRow = function (a) {
        this.expandRow_(!0, a)
    }, o.prototype.collapseRow = function (a) {
        this.expandRow_(!1, a)
    }, o.prototype.expandAllRows = function (b) {
        if (b) {
            var d = this.$body.find(c('> tr[data-index="%s"]', 0)),
                e = this,
                f = null,
                g = !1,
                h = -1;
            if (d.next().is("tr.detail-view") ? d.next().next().is("tr.detail-view") || (d.next().find(".detail-icon").click(), g = !0) : (d.find("> td > .detail-icon").click(), g = !0), g) try {
                h = setInterval(function () {
                    f = e.$body.find("tr.detail-view").last().find(".detail-icon"), f.length > 0 ? f.click() : clearInterval(h)
                }, 1)
            } catch (i) {
                clearInterval(h)
            }
        } else
            for (var j = this.$body.children(), k = 0; k < j.length; k++) this.expandRow_(!0, a(j[k]).data("index"))
    }, o.prototype.collapseAllRows = function (b) {
        if (b) this.expandRow_(!1, 0);
        else
            for (var c = this.$body.children(), d = 0; d < c.length; d++) this.expandRow_(!1, a(c[d]).data("index"))
    }, o.prototype.updateFormatText = function (a, b) {
        this.options[c("format%s", a)] && ("string" == typeof b ? this.options[c("format%s", a)] = function () {
            return b
        } : "function" == typeof b && (this.options[c("format%s", a)] = b)), this.initToolbar(), this.initPagination(), this.initBody()
    };
    var p = ["getOptions", "getSelections", "getAllSelections", "getData", "load", "append", "prepend", "remove", "removeAll", "insertRow", "updateRow", "updateCell", "updateByUniqueId", "removeByUniqueId", "getRowByUniqueId", "showRow", "hideRow", "getHiddenRows", "mergeCells", "checkAll", "uncheckAll", "checkInvert", "check", "uncheck", "checkBy", "uncheckBy", "refresh", "resetView", "resetWidth", "destroy", "showLoading", "hideLoading", "showColumn", "hideColumn", "getHiddenColumns", "getVisibleColumns", "showAllColumns", "hideAllColumns", "filterBy", "scrollTo", "getScrollPosition", "selectPage", "prevPage", "nextPage", "togglePagination", "toggleView", "refreshOptions", "resetSearch", "expandRow", "collapseRow", "expandAllRows", "collapseAllRows", "updateFormatText"];
    a.fn.bootstrapTable = function (b) {
        var c, d = Array.prototype.slice.call(arguments, 1);
        return this.each(function () {
            var e = a(this),
                f = e.data("bootstrap.table"),
                g = a.extend({}, o.DEFAULTS, e.data(), "object" == typeof b && b);
            if ("string" == typeof b) {
                if (a.inArray(b, p) < 0) throw new Error("Unknown method: " + b);
                if (!f) return;
                c = f[b].apply(f, d), "destroy" === b && e.removeData("bootstrap.table")
            }
            f || e.data("bootstrap.table", f = new o(this, g))
        }), "undefined" == typeof c ? this : c
    }, a.fn.bootstrapTable.Constructor = o, a.fn.bootstrapTable.defaults = o.DEFAULTS, a.fn.bootstrapTable.columnDefaults = o.COLUMN_DEFAULTS, a.fn.bootstrapTable.locales = o.LOCALES, a.fn.bootstrapTable.methods = p, a.fn.bootstrapTable.utils = {
        sprintf: c,
        getFieldIndex: e,
        compareObjects: i,
        calculateObjectValue: h,
        getItemField: l,
        objectKeys: n,
        isIEBrowser: m
    }, a(function () {
        a('[data-toggle="table"]').bootstrapTable()
    })
}(jQuery);
define("bootstrap-table", ["bootstrap"], (function (global) {
    return function () {
        var ret, fn;
        return ret || global.$.fn.bootstrapTable;
    };
}(this)));

(function ($) {
    'use strict';
    $.extend($.fn.bootstrapTable.defaults, {
        // 默认不显示
        paginationShowPageGo: true
    });

    $.extend($.fn.bootstrapTable.locales, {
        pageGo: function () {
            return '';
        }
    });
    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales);

    var BootstrapTable = $.fn.bootstrapTable.Constructor,
        _initPagination = BootstrapTable.prototype.initPagination;

    BootstrapTable.prototype.initPagination = function () {
        _initPagination.apply(this, Array.prototype.slice.apply(arguments));
        if (this.options.paginationShowPageGo) {
            var html = [];

            html.push(
                '<ul class="pagination-jump">',
                '<li class=""><span>' + this.options.pageGo() + '</span></li>',
                '<li class=""><input type="text" class="page-input" value="' + this.options.pageNumber + '"   /></li>',
                '<li class="page-go"><a class="jump-go" href="">GO</a></li>',
                '</ul>');
            this.$pagination.find('ul.pagination').after(html.join(''));

            this.$pagination.find('.page-go').off('click').on('click', $.proxy(this.onPageGo, this));
            this.$pagination.find('.page-input').off('keyup').on('keyup', function () {
                this.value = this.value.length == 1 ? this.value.replace(/[^1-9]/g, '') : this.value.replace(/\D/g, '');
            });
            this.$pagination.find('.page-input').off('keydown').on('keydown', function (event) {
                if (event.keyCode == 13) {
                    $('.jump-go').click();
                }
            });
        }
    };

    BootstrapTable.prototype.onPageGo = function (event) {
        // var $this = $(event.currentTarget);
        var $toPage = this.$pagination.find('.page-input');

        if (this.options.pageNumber === +$toPage.val()) {
            return false;
        }
        this.selectPage(+$toPage.val());
        // this.options.pageNumber = +$toPage.val();

        // this.updatePagination(event);
        // $this.prev().find('input').val(this.options.pageNumber);
        return false;
    };
})(jQuery);
define("bootstrap-table-pagejump", ["bootstrap-table"], (function (global) {
    return function () {
        var ret, fn;
        return ret || global.$.fn.bootstrapTable.defaults;
    };
}(this)));

define('backend-init', ['backend', 'bootstrap-table-pagejump'], function (Backend, undefined) {

    var mask_doms = $(".content_mask");
    $.each(mask_doms, function (k, v) {
        var mask_dom = $(mask_doms[k]);
        var mask_symbol = "*";
        switch (mask_dom[0].tagName) {
            case "TEXTAREA":
            case "INPUT":
            case "SPAN":
                var result = mask_init(mask_dom, mask_dom[0].tagName, mask_symbol);

                if (result == false) return true;
                break;
            default:
                Toastr.error('当前使用mask类型不存在');
                return true;
        }
    })


    /*  编辑  */
    var mark_edits = $(".content_mask_edit");
    $.each(mark_edits, function (k, v) {
        var mark_edit = $(mark_edits[k]);

        var mask_dom = $(mask_doms[k]);
        var mask_show_dom = mask_dom.next();
        var mask_hide_dom = mask_dom.next().next();

        switch (mask_dom[0].tagName) {
            case "INPUT":
                if (mask_dom.attr('type') != "text") return true;
                if (mask_dom.val() == "") return true;
                break;
            case "TEXTAREA":
                if (mask_dom.text() == "") return true;
                break;
            case "SPAN":
                if (mask_dom.text() == "") return true;
                break;

            default:
                Toastr.error('当前使用mask类型不存在');
                return true;

        }

        mark_edit.click(function () {
            mask_dom.show();
            mask_show_dom.hide();
            mask_hide_dom.hide();
            mark_edit.hide();
            mask_hide_dom.parent().removeClass('form-control-static');
            var content_mask_operate = $($(content_mask_operates[k]).children()[0]);
            content_mask_operate.children('.content_mask_opera_change').removeClass('fa-eye-slash').addClass('fa-eye');
        });
    })


    /*  操作  */
    var content_mask_operates = $(".content_mask_operate");
    $.each(content_mask_operates, function (k, v) {

        var content_mask_operate = $($(content_mask_operates[k]).children()[0]);

        var mark_edit = $(mark_edits[k]);

        var mask_dom = $(mask_doms[k]);
        var mask_show_dom = mask_dom.next();
        var mask_hide_dom = mask_dom.next().next();


        switch (mask_dom[0].tagName) {
            case "INPUT":
                if (mask_dom.attr('type') != "text") return true;
                if (mask_dom.val() == "") return true;
                break;
            case "TEXTAREA":
                if (mask_dom.text() == "") return true;
                break;
            case "SPAN":
                if (mask_dom.text() == "") return true;
                break;

            default:
                Toastr.error('当前使用mask类型不存在');
                return true;

        }

        content_mask_operate.html(content_mask_operate.html() + "&emsp;<i class='fa fa-eye-slash content_mask_opera_change'></i>");

        content_mask_operate.click(function () {
            var opera_change = content_mask_operate.children('.content_mask_opera_change');
            if ($(opera_change).hasClass('fa-eye-slash')) {
                mask_show_dom.show();
                mask_hide_dom.hide();
                mask_dom.hide();
                $(opera_change).removeClass('fa-eye-slash').addClass('fa-eye');
            } else {
                mask_show_dom.hide();
                mask_hide_dom.show();
                mask_dom.hide();
                $(opera_change).removeClass('fa-eye').addClass('fa-eye-slash');
            }
            mask_hide_dom.parent().removeClass('form-control-static').addClass('form-control-static');
            mask_show_dom.parent().removeClass('form-control-static').addClass('form-control-static');
            mark_edit.show();
        })

        mask_dom.parent().children('.content_mask_change').click(function () {
            var opera_change = content_mask_operate.children('.content_mask_opera_change');
            if ($(opera_change).hasClass('fa-eye-slash')) {
                mask_show_dom.show();
                mask_hide_dom.hide();
                mask_dom.hide();
                $(opera_change).removeClass('fa-eye-slash').addClass('fa-eye');
            } else {
                mask_show_dom.hide();
                mask_hide_dom.show();
                mask_dom.hide();
                $(opera_change).removeClass('fa-eye').addClass('fa-eye-slash');
            }
            mask_hide_dom.parent().removeClass('form-control-static').addClass('form-control-static');
            mask_show_dom.parent().removeClass('form-control-static').addClass('form-control-static');
            mark_edit.show();
        })


    });

    if (content_mask_operates.length !== mask_doms.length)
        Toastr.error('请联系客服,检查mask');


    /* 初始化 */
    function mask_init(dom, type, mask_symbol) {
        var mask_dom = dom;

        // switch (type) {
        //     case "INPUT":
        //         if (mask_dom.attr('type') != "text") return true;
        //         if (mask_dom.val() == "") return true;
        //         break;
        //     case "TEXTAREA":
        //         if (mask_dom.text() == "") return true;
        //         break;
        //     case "SPAN":
        //         if (mask_dom.text() == "") return true;
        //         break;
        //     default:
        //         Toastr.error('当前使用mask类型不存在');
        //         return true;
        //
        // }

        /* 遮罩 元素 */
        var mask_attr = "";
        mask_dom.each(function () {
            $.each(this.attributes, function () {
                if (this.specified) {
                    // if (this.name != "class" && this.name != "name" && this.name != "style") {
                    //     mask_attr += " " + this.name + "='" + this.value + "' ";
                    // }

                    switch (type) {
                        case "SPAN":
                            mask_attr += "";
                            break;
                        default:
                            mask_attr += "  style='word-break: normal; width: auto; white-space: pre-wrap; overflow-wrap: break-word; overflow: hidden;'";
                    }
                }
            });
        });

        /* hide */
        var mask_html_hide_content = "";
        for (var i = 0; i <= 5; i++) {
            mask_html_hide_content += mask_symbol;
        }

        var mask_html_hide = "";
        switch (type) {
            case "INPUT":
            case "TEXTAREA":
                if (mask_dom.val() == "") {
                    mask_html_hide = "<span class='content_mask_change hide ' " + mask_attr + ">" + mask_html_hide_content + "</span>&emsp;<i class='fa fa-pencil-square-o content_mask_edit hide'></i>";
                } else {
                    mask_html_hide = "<span class='content_mask_change' " + mask_attr + ">" + mask_html_hide_content + "</span>&emsp;<i class='fa fa-pencil-square-o content_mask_edit'></i>";
                }

                break;
            case "SPAN":
                if (mask_dom.text() == "") {
                    mask_html_hide = "<span class='content_mask_change hide ' " + mask_attr + ">" + mask_html_hide_content + "</span>&emsp;<i class='content_mask_edit hide'></i>";
                } else {
                    mask_html_hide = "<span class='content_mask_change' " + mask_attr + ">" + mask_html_hide_content + "</span>&emsp;<i class='content_mask_edit'></i>";
                }

                break;
            default:
                Toastr.error('当前使用mask类型不存在');
                return false;
        }
        mask_dom.after(mask_html_hide);

        /* show */
        switch (type) {
            case "INPUT":
            case "TEXTAREA":
                if (mask_dom.val() == "") {
                    mask_html_hide = "<span class='content_mask_change hide ' " + mask_attr + ">" + mask_dom.val() + "</span>";
                    mask_dom.after(mask_html_hide);
                    return false;
                } else {
                    mask_html_hide = "<span class='content_mask_change' " + mask_attr + ">" + mask_dom.val() + "</span>";
                }
                break;
            case "SPAN":
                if (mask_dom.text() == "") {
                    mask_html_hide = "<span class='content_mask_change hide ' " + mask_attr + ">" + mask_dom.text() + "</span>";
                    mask_dom.after(mask_html_hide);
                    return false;
                } else {
                    mask_html_hide = "<span class='content_mask_change' " + mask_attr + ">" + mask_dom.text() + "</span>";
                }
                break;
            default:
                Toastr.error('当前使用mask类型不存在');
                return false;
        }
        mask_dom.after(mask_html_hide);

        var mask_show_dom = mask_dom.next();
        var mask_hide_dom = mask_dom.next().next();

        /* 初始元素 */
        mask_dom.hide();
        mask_show_dom.hide();
        mask_hide_dom.parent().removeClass('form-control-static').addClass('form-control-static');
        mask_show_dom.parent().removeClass('form-control-static').addClass('form-control-static');
    }


    $(function () {
        /* emojis */
        let emojis = $(".emojis");
        if (emojis.length > 0) {
            $("<link>").attr({
                rel: "stylesheet",
                type: "text/css",
                href: "/assets/libs/emojis/emoji.css"
            }).appendTo("head");
            require(['/assets/libs/emojis/emojisort.js', '/assets/libs/emojis/emoji.js'], function (undefined, undefined) {
                emojis.after('<div class="faceDivBox">\n' +
                    '        <div class="faceDiv">\n' +
                    '            <section class="emoji-box"></section>\n' +
                    '            <div class="tabbox">\n' +
                    '                <section class="emoji-tab"></section>\n' +
                    '            </div>\n' +
                    '        </div>\n' +
                    '        <a class="closeFaceBox" href="javascript:void(0)"><img width="20"\n' +
                    '                src="https://img.huajuanyun.com/emojiV2/close.png" alt=""></a>\n' +
                    '    </div>');
                emojis.after('<div class="emoji-open-face" style="cursor:pointer"><img src="https://img.huajuanyun.com/emojiV2/icon.png" title="添加表情" alt=""> <a data-href="https://h5.dhcc.wang/emoji/index.html" class="btn-dialog-emoji">查看更多emoji表情</a><div/>');
                emojis.after('');
                sdEditorEmoj.Init(emojiconfig);
                sdEditorEmoj.setEmoji({
                    type: 'input',
                    id: null,
                    document: null
                });
            });
        }
    })

    /**
     * 获取url请求参数
     * @param url
     * @param value
     * @returns {null|*}
     */
    window.getQueryVariable = function (url, value) {
        var vars = url.split("?")[1].split("&");
        for (var i = 0; i < vars.length; i++) {
            var pair = vars[i].split("=");
            if (pair[0] === value) {
                return pair[1];
            }
        }
        return null;
    };

});
//! moment.js locale configuration
//! locale : Chinese (China) [zh-cn]
//! author : suupic : https://github.com/suupic
//! author : Zeno Zeng : https://github.com/zenozeng

;
(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' &&
        typeof require === 'function' ? factory(require('../moment')) :
        typeof define === 'function' && define.amd ? define('moment/locale/zh-cn', ['../moment'], factory) :
        factory(global.moment)
}(this, function (moment) {
    'use strict';


    var zh_cn = moment.defineLocale('zh-cn', {
        months: '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),
        monthsShort: '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),
        weekdays: '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),
        weekdaysShort: '周日_周一_周二_周三_周四_周五_周六'.split('_'),
        weekdaysMin: '日_一_二_三_四_五_六'.split('_'),
        longDateFormat: {
            LT: 'Ah点mm分',
            LTS: 'Ah点m分s秒',
            L: 'YYYY-MM-DD',
            LL: 'YYYY年MMMD日',
            LLL: 'YYYY年MMMD日Ah点mm分',
            LLLL: 'YYYY年MMMD日ddddAh点mm分',
            l: 'YYYY-MM-DD',
            ll: 'YYYY年MMMD日',
            lll: 'YYYY年MMMD日Ah点mm分',
            llll: 'YYYY年MMMD日ddddAh点mm分'
        },
        meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,
        meridiemHour: function (hour, meridiem) {
            if (hour === 12) {
                hour = 0;
            }
            if (meridiem === '凌晨' || meridiem === '早上' ||
                meridiem === '上午') {
                return hour;
            } else if (meridiem === '下午' || meridiem === '晚上') {
                return hour + 12;
            } else {
                // '中午'
                return hour >= 11 ? hour : hour + 12;
            }
        },
        meridiem: function (hour, minute, isLower) {
            var hm = hour * 100 + minute;
            if (hm < 600) {
                return '凌晨';
            } else if (hm < 900) {
                return '早上';
            } else if (hm < 1130) {
                return '上午';
            } else if (hm < 1230) {
                return '中午';
            } else if (hm < 1800) {
                return '下午';
            } else {
                return '晚上';
            }
        },
        calendar: {
            sameDay: function () {
                return this.minutes() === 0 ? '[今天]Ah[点整]' : '[今天]LT';
            },
            nextDay: function () {
                return this.minutes() === 0 ? '[明天]Ah[点整]' : '[明天]LT';
            },
            lastDay: function () {
                return this.minutes() === 0 ? '[昨天]Ah[点整]' : '[昨天]LT';
            },
            nextWeek: function () {
                var startOfWeek, prefix;
                startOfWeek = moment().startOf('week');
                prefix = this.diff(startOfWeek, 'days') >= 7 ? '[下]' : '[本]';
                return this.minutes() === 0 ? prefix + 'dddAh点整' : prefix + 'dddAh点mm';
            },
            lastWeek: function () {
                var startOfWeek, prefix;
                startOfWeek = moment().startOf('week');
                prefix = this.unix() < startOfWeek.unix() ? '[上]' : '[本]';
                return this.minutes() === 0 ? prefix + 'dddAh点整' : prefix + 'dddAh点mm';
            },
            sameElse: 'LL'
        },
        ordinalParse: /\d{1,2}(日|月|周)/,
        ordinal: function (number, period) {
            switch (period) {
                case 'd':
                case 'D':
                case 'DDD':
                    return number + '日';
                case 'M':
                    return number + '月';
                case 'w':
                case 'W':
                    return number + '周';
                default:
                    return number;
            }
        },
        relativeTime: {
            future: '%s内',
            past: '%s前',
            s: '几秒',
            m: '1 分钟',
            mm: '%d 分钟',
            h: '1 小时',
            hh: '%d 小时',
            d: '1 天',
            dd: '%d 天',
            M: '1 个月',
            MM: '%d 个月',
            y: '1 年',
            yy: '%d 年'
        },
        week: {
            // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效
            dow: 1, // Monday is the first day of the week.
            doy: 4 // The week that contains Jan 4th is the first week of the year.
        }
    });

    return zh_cn;

}));
/**
 * Bootstrap Table Chinese translation
 * Author: Zhixin Wen<wenzhixin2010@gmail.com>
 */
(function ($) {
    'use strict';

    $.fn.bootstrapTable.locales['zh-CN'] = {
        formatLoadingMessage: function () {
            return '正在努力地加载数据中，请稍候……';
        },
        formatRecordsPerPage: function (pageNumber) {
            return '每页显示 ' + pageNumber + ' 条记录';
        },
        formatShowingRows: function (pageFrom, pageTo, totalRows) {
            return '显示第 ' + pageFrom + ' 到第 ' + pageTo + ' 条记录，总共 ' + totalRows + ' 条记录';
        },
        formatSearch: function () {
            return '搜索';
        },
        formatNoMatches: function () {
            return '没有找到匹配的记录';
        },
        formatPaginationSwitch: function () {
            return '隐藏/显示分页';
        },
        formatRefresh: function () {
            return '刷新';
        },
        formatToggle: function () {
            return '切换';
        },
        formatColumns: function () {
            return '列';
        },
        formatExport: function () {
            return '导出数据';
        },
        formatClearFilters: function () {
            return '清空过滤';
        }
    };

    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['zh-CN']);

})(jQuery);

define("bootstrap-table-lang", ["bootstrap-table"], (function (global) {
    return function () {
        var ret, fn;
        return ret || global.$.fn.bootstrapTable.defaults;
    };
}(this)));

/*
 tableExport.jquery.plugin

 Version 1.9.11

 Copyright (c) 2015-2018 hhurz, https://github.com/hhurz

 Original Work Copyright (c) 2014 Giri Raj

 Licensed under the MIT License
*/
var $jscomp = $jscomp || {};
$jscomp.scope = {};
$jscomp.findInternal = function (c, g, u) {
    c instanceof String && (c = String(c));
    for (var C = c.length, D = 0; D < C; D++) {
        var P = c[D];
        if (g.call(u, P, D, c)) return {
            i: D,
            v: P
        }
    }
    return {
        i: -1,
        v: void 0
    }
};
$jscomp.ASSUME_ES5 = !1;
$jscomp.ASSUME_NO_NATIVE_MAP = !1;
$jscomp.ASSUME_NO_NATIVE_SET = !1;
$jscomp.defineProperty = $jscomp.ASSUME_ES5 || "function" == typeof Object.defineProperties ? Object.defineProperty : function (c, g, u) {
    c != Array.prototype && c != Object.prototype && (c[g] = u.value)
};
$jscomp.getGlobal = function (c) {
    return "undefined" != typeof window && window === c ? c : "undefined" != typeof global && null != global ? global : c
};
$jscomp.global = $jscomp.getGlobal(this);
$jscomp.polyfill = function (c, g, u, C) {
    if (g) {
        u = $jscomp.global;
        c = c.split(".");
        for (C = 0; C < c.length - 1; C++) {
            var D = c[C];
            D in u || (u[D] = {});
            u = u[D]
        }
        c = c[c.length - 1];
        C = u[c];
        g = g(C);
        g != C && null != g && $jscomp.defineProperty(u, c, {
            configurable: !0,
            writable: !0,
            value: g
        })
    }
};
$jscomp.polyfill("Array.prototype.find", function (c) {
    return c ? c : function (c, u) {
        return $jscomp.findInternal(this, c, u).v
    }
}, "es6", "es3");
(function (c) {
    c.fn.tableExport = function (g) {
        function u(b) {
            var d = [];
            C(b, "tbody").each(function () {
                d.push.apply(d, D(c(this), a.tbodySelector).toArray())
            });
            a.tfootSelector.length && C(b, "tfoot").each(function () {
                d.push.apply(d, D(c(this), a.tfootSelector).toArray())
            });
            return d
        }

        function C(b, a) {
            var d = b.parents("table").length;
            return b.find(a).filter(function () {
                return c(this).closest("table").parents("table").length === d
            })
        }

        function D(b, d) {
            return b.find(d).filter(function () {
                return 0 === a.maxNestedTables || c(this).find("table").length <
                    a.maxNestedTables && c(this).parents("table").length <= a.maxNestedTables
            })
        }

        function P(b) {
            var a = [];
            c(b).find("thead").first().find("th").each(function (b, d) {
                void 0 !== c(d).attr("data-field") ? a[b] = c(d).attr("data-field") : a[b] = b.toString()
            });
            return a
        }

        function Q(b) {
            var a = "undefined" !== typeof b[0].cellIndex,
                e = "undefined" !== typeof b[0].rowIndex,
                t = a || e ? Aa(b) : b.is(":visible"),
                h = b.data("tableexport-display");
            a && "none" !== h && "always" !== h && (b = c(b[0].parentNode), e = "undefined" !== typeof b[0].rowIndex, h = b.data("tableexport-display"));
            e && "none" !== h && "always" !== h && (h = b.closest("table").data("tableexport-display"));
            return "none" !== h && (!0 === t || "always" === h)
        }

        function Aa(b) {
            var a = [];
            U && (a = I.filter(function () {
                var a = !1;
                this.nodeType === b[0].nodeType && ("undefined" !== typeof this.rowIndex && this.rowIndex === b[0].rowIndex ? a = !0 : "undefined" !== typeof this.cellIndex && this.cellIndex === b[0].cellIndex && "undefined" !== typeof this.parentNode.rowIndex && "undefined" !== typeof b[0].parentNode.rowIndex && this.parentNode.rowIndex === b[0].parentNode.rowIndex && (a = !0));
                return a
            }));
            return !1 === U || 0 === a.length
        }

        function Ba(b, d, e) {
            var t = !1;
            Q(b) ? 0 < a.ignoreColumn.length && (-1 !== c.inArray(e, a.ignoreColumn) || -1 !== c.inArray(e - d, a.ignoreColumn) || R.length > e && "undefined" !== typeof R[e] && -1 !== c.inArray(R[e], a.ignoreColumn)) && (t = !0) : t = !0;
            return t
        }

        function B(b, d, e, t, h) {
            if ("function" === typeof h) {
                var l = !1;
                "function" === typeof a.onIgnoreRow && (l = a.onIgnoreRow(c(b), e));
                if (!1 === l && -1 === c.inArray(e, a.ignoreRow) && -1 === c.inArray(e - t, a.ignoreRow) && Q(c(b))) {
                    var w = c(b).find(d),
                        p = 0;
                    w.each(function (b) {
                        var a =
                            c(this),
                            d, l = S(this),
                            t = T(this);
                        c.each(F, function () {
                            if (e >= this.s.r && e <= this.e.r && p >= this.s.c && p <= this.e.c)
                                for (d = 0; d <= this.e.c - this.s.c; ++d) h(null, e, p++)
                        });
                        if (!1 === Ba(a, w.length, b)) {
                            if (t || l) l = l || 1, F.push({
                                s: {
                                    r: e,
                                    c: p
                                },
                                e: {
                                    r: e + (t || 1) - 1,
                                    c: p + l - 1
                                }
                            });
                            h(this, e, p++)
                        }
                        if (l)
                            for (d = 0; d < l - 1; ++d) h(null, e, p++)
                    });
                    c.each(F, function () {
                        if (e >= this.s.r && e <= this.e.r && p >= this.s.c && p <= this.e.c)
                            for (aa = 0; aa <= this.e.c - this.s.c; ++aa) h(null, e, p++)
                    })
                }
            }
        }

        function na(b, d) {
            if ("string" === a.outputMode) return b.output();
            if ("base64" === a.outputMode) return J(b.output());
            if ("window" === a.outputMode) window.URL = window.URL || window.webkitURL, window.open(window.URL.createObjectURL(b.output("blob")));
            else try {
                var e = b.output("blob");
                saveAs(e, a.fileName + ".pdf")
            } catch (t) {
                G(a.fileName + ".pdf", "data:application/pdf" + (d ? "" : ";base64") + ",", d ? b.output("blob") : b.output())
            }
        }

        function oa(b, a, e) {
            var d = 0;
            "undefined" !== typeof e && (d = e.colspan);
            if (0 <= d) {
                for (var h = b.width, c = b.textPos.x, w = a.table.columns.indexOf(a.column), p = 1; p < d; p++) h += a.table.columns[w + p].width;
                1 < d && ("right" === b.styles.halign ?
                    c = b.textPos.x + h - b.width : "center" === b.styles.halign && (c = b.textPos.x + (h - b.width) / 2));
                b.width = h;
                b.textPos.x = c;
                "undefined" !== typeof e && 1 < e.rowspan && (b.height *= e.rowspan);
                if ("middle" === b.styles.valign || "bottom" === b.styles.valign) e = ("string" === typeof b.text ? b.text.split(/\r\n|\r|\n/g) : b.text).length || 1, 2 < e && (b.textPos.y -= (2 - 1.15) / 2 * a.row.styles.fontSize * (e - 2) / 3);
                return !0
            }
            return !1
        }

        function pa(b, a, e) {
            "undefined" !== typeof e.images && a.each(function () {
                var a = c(this).children();
                if (c(this).is("img")) {
                    var d = qa(this.src);
                    e.images[d] = {
                        url: this.src,
                        src: this.src
                    }
                }
                "undefined" !== typeof a && 0 < a.length && pa(b, a, e)
            })
        }

        function Ca(b, a) {
            function d(b) {
                if (b.url) {
                    var d = new Image;
                    h = ++l;
                    d.crossOrigin = "Anonymous";
                    d.onerror = d.onload = function () {
                        if (d.complete && (0 === d.src.indexOf("data:image/") && (d.width = b.width || d.width || 0, d.height = b.height || d.height || 0), d.width + d.height)) {
                            var e = document.createElement("canvas"),
                                c = e.getContext("2d");
                            e.width = d.width;
                            e.height = d.height;
                            c.drawImage(d, 0, 0);
                            b.src = e.toDataURL("image/jpeg")
                        }--l || a(h)
                    };
                    d.src = b.url
                }
            }
            var c, h = 0,
                l = 0;
            if ("undefined" !== typeof b.images)
                for (c in b.images) b.images.hasOwnProperty(c) && d(b.images[c]);
            (b = l) || (a(h), b = void 0);
            return b
        }

        function ra(b, d, e) {
            d.each(function () {
                var d = c(this).children(),
                    h = 0;
                if (c(this).is("div")) {
                    var l = ba(K(this, "background-color"), [255, 255, 255]),
                        w = ba(K(this, "border-top-color"), [0, 0, 0]),
                        p = ca(this, "border-top-width", a.jspdf.unit),
                        f = this.getBoundingClientRect(),
                        g = this.offsetLeft * e.dw;
                    h = this.offsetTop * e.dh;
                    var k = f.width * e.dw;
                    f = f.height * e.dh;
                    e.doc.setDrawColor.apply(void 0,
                        w);
                    e.doc.setFillColor.apply(void 0, l);
                    e.doc.setLineWidth(p);
                    e.doc.rect(b.x + g, b.y + h, k, f, p ? "FD" : "F")
                } else if (c(this).is("img") && "undefined" !== typeof e.images && (l = qa(this.src), l = e.images[l], "undefined" !== typeof l)) {
                    w = b.width / b.height;
                    p = this.width / this.height;
                    g = b.width;
                    k = b.height;
                    f = 19.049976 / 25.4;
                    p <= w ? (k = Math.min(b.height, this.height), g = this.width * k / this.height) : p > w && (g = Math.min(b.width, this.width), k = this.height * g / this.width);
                    g *= f;
                    k *= f;
                    k < b.height && (h = (b.height - k) / 2);
                    try {
                        e.doc.addImage(l.src, b.textPos.x,
                            b.y + h, g, k)
                    } catch (Ga) {}
                    b.textPos.x += g
                }
                "undefined" !== typeof d && 0 < d.length && ra(b, d, e)
            })
        }

        function sa(b, a, e) {
            if ("function" === typeof e.onAutotableText) e.onAutotableText(e.doc, b, a);
            else {
                var d = b.textPos.x,
                    h = b.textPos.y,
                    l = {
                        halign: b.styles.halign,
                        valign: b.styles.valign
                    };
                if (a.length) {
                    for (a = a[0]; a.previousSibling;) a = a.previousSibling;
                    for (var w = !1, p = !1; a;) {
                        var f = a.innerText || a.textContent || "";
                        f = (f.length && " " === f[0] ? " " : "") + c.trim(f) + (1 < f.length && " " === f[f.length - 1] ? " " : "");
                        c(a).is("br") && (d = b.textPos.x, h += e.doc.internal.getFontSize());
                        c(a).is("b") ? w = !0 : c(a).is("i") && (p = !0);
                        (w || p) && e.doc.setFontType(w && p ? "bolditalic" : w ? "bold" : "italic");
                        var g = e.doc.getStringUnitWidth(f) * e.doc.internal.getFontSize();
                        if (g) {
                            if ("linebreak" === b.styles.overflow && d > b.textPos.x && d + g > b.textPos.x + b.width) {
                                if (0 <= ".,!%*;:=-".indexOf(f.charAt(0))) {
                                    var k = f.charAt(0);
                                    g = e.doc.getStringUnitWidth(k) * e.doc.internal.getFontSize();
                                    d + g <= b.textPos.x + b.width && (e.doc.autoTableText(k, d, h, l), f = f.substring(1, f.length));
                                    g = e.doc.getStringUnitWidth(f) * e.doc.internal.getFontSize()
                                }
                                d =
                                    b.textPos.x;
                                h += e.doc.internal.getFontSize()
                            }
                            if ("visible" !== b.styles.overflow)
                                for (; f.length && d + g > b.textPos.x + b.width;) f = f.substring(0, f.length - 1), g = e.doc.getStringUnitWidth(f) * e.doc.internal.getFontSize();
                            e.doc.autoTableText(f, d, h, l);
                            d += g
                        }
                        if (w || p) c(a).is("b") ? w = !1 : c(a).is("i") && (p = !1), e.doc.setFontType(w || p ? w ? "bold" : "italic" : "normal");
                        a = a.nextSibling
                    }
                    b.textPos.x = d;
                    b.textPos.y = h
                } else e.doc.autoTableText(b.text, b.textPos.x, b.textPos.y, l)
            }
        }

        function da(b, a, e) {
            return b.replace(new RegExp(a.replace(/([.*+?^=!:${}()|\[\]\/\\])/g,
                "\\$1"), "g"), e)
        }

        function ha(b) {
            b = da(b || "0", a.numbers.html.thousandsSeparator, "");
            b = da(b, a.numbers.html.decimalMark, ".");
            return "number" === typeof b || !1 !== jQuery.isNumeric(b) ? b : !1
        }

        function Da(b) {
            -1 < b.indexOf("%") ? (b = ha(b.replace(/%/g, "")), !1 !== b && (b /= 100)) : b = !1;
            return b
        }

        function z(b, d, e) {
            var t = "";
            if (null !== b) {
                var h = c(b);
                if (h[0].hasAttribute("data-tableexport-value")) var l = (l = h.data("tableexport-value")) ? l + "" : "";
                else if (l = h.html(), "function" === typeof a.onCellHtmlData) l = a.onCellHtmlData(h, d, e, l);
                else if ("" !==
                    l) {
                    var f = c.parseHTML(l),
                        p = 0,
                        g = 0;
                    l = "";
                    c.each(f, function () {
                        if (c(this).is("input")) l += h.find("input").eq(p++).val();
                        else if (c(this).is("select")) l += h.find("select option:selected").eq(g++).text();
                        else if ("undefined" === typeof c(this).html()) l += c(this).text();
                        else if (void 0 === jQuery().bootstrapTable || !0 !== c(this).hasClass("filterControl") && 0 === c(b).parents(".detail-view").length) l += c(this).html()
                    })
                }
                if (!0 === a.htmlContent) t = c.trim(l);
                else if (l && "" !== l)
                    if ("" !== c(b).data("tableexport-cellformat")) {
                        var k = l.replace(/\n/g,
                                "\u2028").replace(/<br\s*[\/]?>/gi, "\u2060"),
                            m = c("<div/>").html(k).contents();
                        f = !1;
                        k = "";
                        c.each(m.text().split("\u2028"), function (b, a) {
                            0 < b && (k += " ");
                            k += c.trim(a)
                        });
                        c.each(k.split("\u2060"), function (b, a) {
                            0 < b && (t += "\n");
                            t += c.trim(a).replace(/\u00AD/g, "")
                        });
                        if ("json" === a.type || "excel" === a.type && "xmlss" === a.mso.fileFormat || !1 === a.numbers.output) f = ha(t), !1 !== f && (t = Number(f));
                        else if (a.numbers.html.decimalMark !== a.numbers.output.decimalMark || a.numbers.html.thousandsSeparator !== a.numbers.output.thousandsSeparator)
                            if (f =
                                ha(t), !1 !== f) {
                                m = ("" + f.substr(0 > f ? 1 : 0)).split(".");
                                1 === m.length && (m[1] = "");
                                var n = 3 < m[0].length ? m[0].length % 3 : 0;
                                t = (0 > f ? "-" : "") + (a.numbers.output.thousandsSeparator ? (n ? m[0].substr(0, n) + a.numbers.output.thousandsSeparator : "") + m[0].substr(n).replace(/(\d{3})(?=\d)/g, "$1" + a.numbers.output.thousandsSeparator) : m[0]) + (m[1].length ? a.numbers.output.decimalMark + m[1] : "")
                            }
                    } else t = l;
                !0 === a.escape && (t = escape(t));
                "function" === typeof a.onCellData && (t = a.onCellData(h, d, e, t))
            }
            return t
        }

        function Ea(b, a, e) {
            return a + "-" +
                e.toLowerCase()
        }

        function ba(b, a) {
            (b = /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/.exec(b)) && (a = [parseInt(b[1]), parseInt(b[2]), parseInt(b[3])]);
            return a
        }

        function ta(b) {
            var a = K(b, "text-align"),
                e = K(b, "font-weight"),
                c = K(b, "font-style"),
                h = "";
            "start" === a && (a = "rtl" === K(b, "direction") ? "right" : "left");
            700 <= e && (h = "bold");
            "italic" === c && (h += c);
            "" === h && (h = "normal");
            a = {
                style: {
                    align: a,
                    bcolor: ba(K(b, "background-color"), [255, 255, 255]),
                    color: ba(K(b, "color"), [0, 0, 0]),
                    fstyle: h
                },
                colspan: S(b),
                rowspan: T(b)
            };
            null !== b &&
                (b = b.getBoundingClientRect(), a.rect = {
                    width: b.width,
                    height: b.height
                });
            return a
        }

        function S(a) {
            var b = c(a).data("tableexport-colspan");
            "undefined" === typeof b && c(a).is("[colspan]") && (b = c(a).attr("colspan"));
            return parseInt(b) || 0
        }

        function T(a) {
            var b = c(a).data("tableexport-rowspan");
            "undefined" === typeof b && c(a).is("[rowspan]") && (b = c(a).attr("rowspan"));
            return parseInt(b) || 0
        }

        function K(a, d) {
            try {
                return window.getComputedStyle ? (d = d.replace(/([a-z])([A-Z])/, Ea), window.getComputedStyle(a, null).getPropertyValue(d)) :
                    a.currentStyle ? a.currentStyle[d] : a.style[d]
            } catch (e) {}
            return ""
        }

        function ca(a, d, e) {
            d = K(a, d).match(/\d+/);
            if (null !== d) {
                d = d[0];
                a = a.parentElement;
                var b = document.createElement("div");
                b.style.overflow = "hidden";
                b.style.visibility = "hidden";
                a.appendChild(b);
                b.style.width = 100 + e;
                e = 100 / b.offsetWidth;
                a.removeChild(b);
                return d * e
            }
            return 0
        }

        function ia() {
            if (!(this instanceof ia)) return new ia;
            this.SheetNames = [];
            this.Sheets = {}
        }

        function ua(a) {
            for (var b = new ArrayBuffer(a.length), e = new Uint8Array(b), c = 0; c !== a.length; ++c) e[c] =
                a.charCodeAt(c) & 255;
            return b
        }

        function Fa(a) {
            for (var b = {}, e = {
                    s: {
                        c: 1E7,
                        r: 1E7
                    },
                    e: {
                        c: 0,
                        r: 0
                    }
                }, c = 0; c !== a.length; ++c)
                for (var h = 0; h !== a[c].length; ++h) {
                    e.s.r > c && (e.s.r = c);
                    e.s.c > h && (e.s.c = h);
                    e.e.r < c && (e.e.r = c);
                    e.e.c < h && (e.e.c = h);
                    var l = {
                        v: a[c][h]
                    };
                    if (null !== l.v) {
                        var f = XLSX.utils.encode_cell({
                            c: h,
                            r: c
                        });
                        if ("number" === typeof l.v) l.t = "n";
                        else if ("boolean" === typeof l.v) l.t = "b";
                        else if (l.v instanceof Date) {
                            l.t = "n";
                            l.z = XLSX.SSF._table[14];
                            var g = l;
                            var k = (Date.parse(l.v) - new Date(Date.UTC(1899, 11, 30))) / 864E5;
                            g.v = k
                        } else l.t =
                            "s";
                        b[f] = l
                    }
                }
            1E7 > e.s.c && (b["!ref"] = XLSX.utils.encode_range(e));
            return b
        }

        function qa(a) {
            var b = 0,
                c;
            if (0 === a.length) return b;
            var f = 0;
            for (c = a.length; f < c; f++) {
                var h = a.charCodeAt(f);
                b = (b << 5) - b + h;
                b |= 0
            }
            return b
        }

        function G(a, c, e) {
            var b = window.navigator.userAgent;
            if (!1 !== a && window.navigator.msSaveOrOpenBlob) window.navigator.msSaveOrOpenBlob(new Blob([e]), a);
            else if (!1 !== a && (0 < b.indexOf("MSIE ") || b.match(/Trident.*rv:11\./))) {
                if (c = document.createElement("iframe")) {
                    document.body.appendChild(c);
                    c.setAttribute("style",
                        "display:none");
                    c.contentDocument.open("txt/plain", "replace");
                    c.contentDocument.write(e);
                    c.contentDocument.close();
                    c.contentDocument.focus();
                    switch (a.substr(a.lastIndexOf(".") + 1)) {
                        case "doc":
                        case "json":
                        case "png":
                        case "pdf":
                        case "xls":
                        case "xlsx":
                            a += ".txt"
                    }
                    c.contentDocument.execCommand("SaveAs", !0, a);
                    document.body.removeChild(c)
                }
            } else {
                var d = document.createElement("a");
                if (d) {
                    var l = null;
                    d.style.display = "none";
                    !1 !== a ? d.download = a : d.target = "_blank";
                    "object" === typeof e ? (window.URL = window.URL || window.webkitURL,
                        l = window.URL.createObjectURL(e), d.href = l) : 0 <= c.toLowerCase().indexOf("base64,") ? d.href = c + J(e) : d.href = c + encodeURIComponent(e);
                    document.body.appendChild(d);
                    if (document.createEvent) null === ea && (ea = document.createEvent("MouseEvents")), ea.initEvent("click", !0, !1), d.dispatchEvent(ea);
                    else if (document.createEventObject) d.fireEvent("onclick");
                    else if ("function" === typeof d.onclick) d.onclick();
                    setTimeout(function () {
                        l && window.URL.revokeObjectURL(l);
                        document.body.removeChild(d)
                    }, 100)
                }
            }
        }

        function J(a) {
            var b, c = "",
                f = 0;
            if ("string" === typeof a) {
                a = a.replace(/\x0d\x0a/g, "\n");
                var h = "";
                for (b = 0; b < a.length; b++) {
                    var l = a.charCodeAt(b);
                    128 > l ? h += String.fromCharCode(l) : (127 < l && 2048 > l ? h += String.fromCharCode(l >> 6 | 192) : (h += String.fromCharCode(l >> 12 | 224), h += String.fromCharCode(l >> 6 & 63 | 128)), h += String.fromCharCode(l & 63 | 128))
                }
                a = h
            }
            for (; f < a.length;) {
                var g = a.charCodeAt(f++);
                h = a.charCodeAt(f++);
                b = a.charCodeAt(f++);
                l = g >> 2;
                g = (g & 3) << 4 | h >> 4;
                var k = (h & 15) << 2 | b >> 6;
                var m = b & 63;
                isNaN(h) ? k = m = 64 : isNaN(b) && (m = 64);
                c = c + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(l) +
                    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(g) + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(k) + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(m)
            }
            return c
        }
        var a = {
                csvEnclosure: '"',
                csvSeparator: ",",
                csvUseBOM: !0,
                displayTableName: !1,
                escape: !1,
                exportHiddenCells: !1,
                fileName: "tableExport",
                htmlContent: !1,
                ignoreColumn: [],
                ignoreRow: [],
                jsonScope: "all",
                jspdf: {
                    orientation: "p",
                    unit: "pt",
                    format: "a4",
                    margins: {
                        left: 20,
                        right: 10,
                        top: 10,
                        bottom: 10
                    },
                    onDocCreated: null,
                    autotable: {
                        styles: {
                            cellPadding: 2,
                            rowHeight: 12,
                            fontSize: 8,
                            fillColor: 255,
                            textColor: 50,
                            fontStyle: "normal",
                            overflow: "ellipsize",
                            halign: "left",
                            valign: "middle"
                        },
                        headerStyles: {
                            fillColor: [52, 73, 94],
                            textColor: 255,
                            fontStyle: "bold",
                            halign: "center"
                        },
                        alternateRowStyles: {
                            fillColor: 245
                        },
                        tableExport: {
                            doc: null,
                            onAfterAutotable: null,
                            onBeforeAutotable: null,
                            onAutotableText: null,
                            onTable: null,
                            outputImages: !0
                        }
                    }
                },
                maxNestedTables: 1,
                mso: {
                    fileFormat: "xlshtml",
                    onMsoNumberFormat: null,
                    pageFormat: "a4",
                    pageOrientation: "portrait",
                    rtl: !1,
                    styles: [],
                    worksheetName: ""
                },
                numbers: {
                    html: {
                        decimalMark: ".",
                        thousandsSeparator: ","
                    },
                    output: {
                        decimalMark: ".",
                        thousandsSeparator: ","
                    }
                },
                onCellData: null,
                onCellHtmlData: null,
                onIgnoreRow: null,
                outputMode: "file",
                pdfmake: {
                    enabled: !1,
                    docDefinition: {
                        pageOrientation: "portrait",
                        defaultStyle: {
                            font: "Roboto"
                        }
                    },
                    fonts: {}
                },
                tbodySelector: "tr",
                tfootSelector: "tr",
                theadSelector: "tr",
                tableName: "Table",
                type: "csv"
            },
            L = {
                a0: [2383.94, 3370.39],
                a1: [1683.78, 2383.94],
                a2: [1190.55, 1683.78],
                a3: [841.89,
                    1190.55
                ],
                a4: [595.28, 841.89],
                a5: [419.53, 595.28],
                a6: [297.64, 419.53],
                a7: [209.76, 297.64],
                a8: [147.4, 209.76],
                a9: [104.88, 147.4],
                a10: [73.7, 104.88],
                b0: [2834.65, 4008.19],
                b1: [2004.09, 2834.65],
                b2: [1417.32, 2004.09],
                b3: [1000.63, 1417.32],
                b4: [708.66, 1000.63],
                b5: [498.9, 708.66],
                b6: [354.33, 498.9],
                b7: [249.45, 354.33],
                b8: [175.75, 249.45],
                b9: [124.72, 175.75],
                b10: [87.87, 124.72],
                c0: [2599.37, 3676.54],
                c1: [1836.85, 2599.37],
                c2: [1298.27, 1836.85],
                c3: [918.43, 1298.27],
                c4: [649.13, 918.43],
                c5: [459.21, 649.13],
                c6: [323.15, 459.21],
                c7: [229.61,
                    323.15
                ],
                c8: [161.57, 229.61],
                c9: [113.39, 161.57],
                c10: [79.37, 113.39],
                dl: [311.81, 623.62],
                letter: [612, 792],
                "government-letter": [576, 756],
                legal: [612, 1008],
                "junior-legal": [576, 360],
                ledger: [1224, 792],
                tabloid: [792, 1224],
                "credit-card": [153, 243]
            },
            v = this,
            ea = null,
            q = [],
            r = [],
            m = 0,
            n = "",
            R = [],
            F = [],
            I = [],
            U = !1;
        c.extend(!0, a, g);
        "xlsx" === a.type && (a.mso.fileFormat = a.type, a.type = "excel");
        "undefined" !== typeof a.excelFileFormat && "undefined" === a.mso.fileFormat && (a.mso.fileFormat = a.excelFileFormat);
        "undefined" !== typeof a.excelPageFormat &&
            "undefined" === a.mso.pageFormat && (a.mso.pageFormat = a.excelPageFormat);
        "undefined" !== typeof a.excelPageOrientation && "undefined" === a.mso.pageOrientation && (a.mso.pageOrientation = a.excelPageOrientation);
        "undefined" !== typeof a.excelRTL && "undefined" === a.mso.rtl && (a.mso.rtl = a.excelRTL);
        "undefined" !== typeof a.excelstyles && "undefined" === a.mso.styles && (a.mso.styles = a.excelstyles);
        "undefined" !== typeof a.onMsoNumberFormat && "undefined" === a.mso.onMsoNumberFormat && (a.mso.onMsoNumberFormat = a.onMsoNumberFormat);
        "undefined" !==
        typeof a.worksheetName && "undefined" === a.mso.worksheetName && (a.mso.worksheetName = a.worksheetName);
        a.mso.pageOrientation = "l" === a.mso.pageOrientation.substr(0, 1) ? "landscape" : "portrait";
        a.maxNestedTables = 0 <= a.maxNestedTables ? a.maxNestedTables : 1;
        R = P(v);
        if ("csv" === a.type || "tsv" === a.type || "txt" === a.type) {
            var M = "",
                X = 0;
            F = [];
            m = 0;
            var ja = function (b, d, e) {
                b.each(function () {
                    n = "";
                    B(this, d, m, e + b.length, function (b, c, d) {
                        var e = n,
                            h = "";
                        if (null !== b)
                            if (b = z(b, c, d), c = null === b || "" === b ? "" : b.toString(), "tsv" === a.type) b instanceof
                        Date && b.toLocaleString(), h = da(c, "\t", " ");
                        else if (b instanceof Date) h = a.csvEnclosure + b.toLocaleString() + a.csvEnclosure;
                        else if (h = da(c, a.csvEnclosure, a.csvEnclosure + a.csvEnclosure), 0 <= h.indexOf(a.csvSeparator) || /[\r\n ]/g.test(h)) h = a.csvEnclosure + h + a.csvEnclosure;
                        n = e + (h + ("tsv" === a.type ? "\t" : a.csvSeparator))
                    });
                    n = c.trim(n).substring(0, n.length - 1);
                    0 < n.length && (0 < M.length && (M += "\n"), M += n);
                    m++
                });
                return b.length
            };
            X += ja(c(v).find("thead").first().find(a.theadSelector), "th,td", X);
            C(c(v), "tbody").each(function () {
                X +=
                    ja(D(c(this), a.tbodySelector), "td,th", X)
            });
            a.tfootSelector.length && ja(c(v).find("tfoot").first().find(a.tfootSelector), "td,th", X);
            M += "\n";
            if ("string" === a.outputMode) return M;
            if ("base64" === a.outputMode) return J(M);
            if ("window" === a.outputMode) {
                G(!1, "data:text/" + ("csv" === a.type ? "csv" : "plain") + ";charset=utf-8,", M);
                return
            }
            try {
                var A = new Blob([M], {
                    type: "text/" + ("csv" === a.type ? "csv" : "plain") + ";charset=utf-8"
                });
                saveAs(A, a.fileName + "." + a.type, "csv" !== a.type || !1 === a.csvUseBOM)
            } catch (b) {
                G(a.fileName + "." + a.type,
                    "data:text/" + ("csv" === a.type ? "csv" : "plain") + ";charset=utf-8," + ("csv" === a.type && a.csvUseBOM ? "\ufeff" : ""), M)
            }
        } else if ("sql" === a.type) {
            m = 0;
            F = [];
            var x = "INSERT INTO `" + a.tableName + "` (";
            q = c(v).find("thead").first().find(a.theadSelector);
            q.each(function () {
                B(this, "th,td", m, q.length, function (a, c, e) {
                    x += "'" + z(a, c, e) + "',"
                });
                m++;
                x = c.trim(x).substring(0, x.length - 1)
            });
            x += ") VALUES ";
            r = u(c(v));
            c(r).each(function () {
                n = "";
                B(this, "td,th", m, q.length + r.length, function (a, c, e) {
                    n += "'" + z(a, c, e) + "',"
                });
                3 < n.length && (x += "(" +
                    n, x = c.trim(x).substring(0, x.length - 1), x += "),");
                m++
            });
            x = c.trim(x).substring(0, x.length - 1);
            x += ";";
            if ("string" === a.outputMode) return x;
            if ("base64" === a.outputMode) return J(x);
            try {
                A = new Blob([x], {
                    type: "text/plain;charset=utf-8"
                }), saveAs(A, a.fileName + ".sql")
            } catch (b) {
                G(a.fileName + ".sql", "data:application/sql;charset=utf-8,", x)
            }
        } else if ("json" === a.type) {
            var V = [];
            F = [];
            q = c(v).find("thead").first().find(a.theadSelector);
            q.each(function () {
                var a = [];
                B(this, "th,td", m, q.length, function (b, c, f) {
                    a.push(z(b, c, f))
                });
                V.push(a)
            });
            var ka = [];
            r = u(c(v));
            c(r).each(function () {
                var a = {},
                    d = 0;
                B(this, "td,th", m, q.length + r.length, function (b, c, h) {
                    V.length ? a[V[V.length - 1][d]] = z(b, c, h) : a[d] = z(b, c, h);
                    d++
                });
                !1 === c.isEmptyObject(a) && ka.push(a);
                m++
            });
            g = "";
            g = "head" === a.jsonScope ? JSON.stringify(V) : "data" === a.jsonScope ? JSON.stringify(ka) : JSON.stringify({
                header: V,
                data: ka
            });
            if ("string" === a.outputMode) return g;
            if ("base64" === a.outputMode) return J(g);
            try {
                A = new Blob([g], {
                    type: "application/json;charset=utf-8"
                }), saveAs(A, a.fileName + ".json")
            } catch (b) {
                G(a.fileName +
                    ".json", "data:application/json;charset=utf-8;base64,", g)
            }
        } else if ("xml" === a.type) {
            m = 0;
            F = [];
            var N = '<?xml version="1.0" encoding="utf-8"?>';
            N += "<tabledata><fields>";
            q = c(v).find("thead").first().find(a.theadSelector);
            q.each(function () {
                B(this, "th,td", m, q.length, function (a, c, e) {
                    N += "<field>" + z(a, c, e) + "</field>"
                });
                m++
            });
            N += "</fields><data>";
            var va = 1;
            r = u(c(v));
            c(r).each(function () {
                var a = 1;
                n = "";
                B(this, "td,th", m, q.length + r.length, function (b, c, f) {
                    n += "<column-" + a + ">" + z(b, c, f) + "</column-" + a + ">";
                    a++
                });
                0 < n.length &&
                    "<column-1></column-1>" !== n && (N += '<row id="' + va + '">' + n + "</row>", va++);
                m++
            });
            N += "</data></tabledata>";
            if ("string" === a.outputMode) return N;
            if ("base64" === a.outputMode) return J(N);
            try {
                A = new Blob([N], {
                    type: "application/xml;charset=utf-8"
                }), saveAs(A, a.fileName + ".xml")
            } catch (b) {
                G(a.fileName + ".xml", "data:application/xml;charset=utf-8;base64,", N)
            }
        } else if ("excel" === a.type && "xmlss" === a.mso.fileFormat) {
            var la = [],
                E = [];
            c(v).filter(function () {
                return Q(c(this))
            }).each(function () {
                function b(a, b, d) {
                    var e = [];
                    c(a).each(function () {
                        var b =
                            0,
                            h = 0;
                        n = "";
                        B(this, "td,th", m, d + a.length, function (a, d, l) {
                            if (null !== a) {
                                var f = "";
                                d = z(a, d, l);
                                l = "String";
                                if (!1 !== jQuery.isNumeric(d)) l = "Number";
                                else {
                                    var g = Da(d);
                                    !1 !== g && (d = g, l = "Number", f += ' ss:StyleID="pct1"')
                                }
                                "Number" !== l && (d = d.replace(/\n/g, "<br>"));
                                g = S(a);
                                a = T(a);
                                c.each(e, function () {
                                    if (m >= this.s.r && m <= this.e.r && h >= this.s.c && h <= this.e.c)
                                        for (var a = 0; a <= this.e.c - this.s.c; ++a) h++, b++
                                });
                                if (a || g) a = a || 1, g = g || 1, e.push({
                                    s: {
                                        r: m,
                                        c: h
                                    },
                                    e: {
                                        r: m + a - 1,
                                        c: h + g - 1
                                    }
                                });
                                1 < g && (f += ' ss:MergeAcross="' + (g - 1) + '"', h += g - 1);
                                1 < a && (f +=
                                    ' ss:MergeDown="' + (a - 1) + '" ss:StyleID="rsp1"');
                                0 < b && (f += ' ss:Index="' + (h + 1) + '"', b = 0);
                                n += "<Cell" + f + '><Data ss:Type="' + l + '">' + c("<div />").text(d).html() + "</Data></Cell>\r";
                                h++
                            }
                        });
                        0 < n.length && (H += '<Row ss:AutoFitHeight="0">\r' + n + "</Row>\r");
                        m++
                    });
                    return a.length
                }
                var d = c(this),
                    e = "";
                "string" === typeof a.mso.worksheetName && a.mso.worksheetName.length ? e = a.mso.worksheetName + " " + (E.length + 1) : "undefined" !== typeof a.mso.worksheetName[E.length] && (e = a.mso.worksheetName[E.length]);
                e.length || (e = d.find("caption").text() ||
                    "");
                e.length || (e = "Table " + (E.length + 1));
                e = c.trim(e.replace(/[\\\/[\]*:?'"]/g, "").substring(0, 31));
                E.push(c("<div />").text(e).html());
                !1 === a.exportHiddenCells && (I = d.find("tr, th, td").filter(":hidden"), U = 0 < I.length);
                m = 0;
                R = P(this);
                H = "<Table>\r";
                e = 0;
                e += b(d.find("thead").first().find(a.theadSelector), "th,td", e);
                b(u(d), "td,th", e);
                H += "</Table>\r";
                la.push(H)
            });
            g = {};
            for (var y = {}, k, O, W = 0, aa = E.length; W < aa; W++) k = E[W], O = g[k], O = g[k] = null == O ? 1 : O + 1, 2 === O && (E[y[k]] = E[y[k]].substring(0, 29) + "-1"), 1 < g[k] ? E[W] = E[W].substring(0,
                29) + "-" + g[k] : y[k] = W;
            g = '<?xml version="1.0" encoding="UTF-8"?>\r<?mso-application progid="Excel.Sheet"?>\r<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"\r xmlns:o="urn:schemas-microsoft-com:office:office"\r xmlns:x="urn:schemas-microsoft-com:office:excel"\r xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"\r xmlns:html="http://www.w3.org/TR/REC-html40">\r<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">\r  <Created>' + (new Date).toISOString() + '</Created>\r</DocumentProperties>\r<OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office">\r  <AllowPNG/>\r</OfficeDocumentSettings>\r<ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">\r  <WindowHeight>9000</WindowHeight>\r  <WindowWidth>13860</WindowWidth>\r  <WindowTopX>0</WindowTopX>\r  <WindowTopY>0</WindowTopY>\r  <ProtectStructure>False</ProtectStructure>\r  <ProtectWindows>False</ProtectWindows>\r</ExcelWorkbook>\r<Styles>\r  <Style ss:ID="Default" ss:Name="Normal">\r    <Alignment ss:Vertical="Bottom"/>\r    <Borders/>\r    <Font/>\r    <Interior/>\r    <NumberFormat/>\r    <Protection/>\r  </Style>\r  <Style ss:ID="rsp1">\r    <Alignment ss:Vertical="Center"/>\r  </Style>\r  <Style ss:ID="pct1">\r    <NumberFormat ss:Format="Percent"/>\r  </Style>\r</Styles>\r';
            for (y = 0; y < la.length; y++) g += '<Worksheet ss:Name="' + E[y] + '" ss:RightToLeft="' + (a.mso.rtl ? "1" : "0") + '">\r' + la[y], g = a.mso.rtl ? g + '<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">\r<DisplayRightToLeft/>\r</WorksheetOptions>\r' : g + '<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel"/>\r', g += "</Worksheet>\r";
            g += "</Workbook>\r";
            if ("string" === a.outputMode) return g;
            if ("base64" === a.outputMode) return J(g);
            try {
                A = new Blob([g], {
                    type: "application/xml;charset=utf-8"
                }), saveAs(A, a.fileName +
                    ".xml")
            } catch (b) {
                G(a.fileName + ".xml", "data:application/xml;charset=utf-8;base64,", g)
            }
        } else if ("excel" === a.type && "xlsx" === a.mso.fileFormat) {
            var wa = [],
                ma = [];
            m = 0;
            r = c(v).find("thead").first().find(a.theadSelector).toArray();
            r.push.apply(r, u(c(v)));
            c(r).each(function () {
                var b = [];
                B(this, "th,td", m, r.length, function (d, e, f) {
                    if ("undefined" !== typeof d && null !== d) {
                        f = z(d, e, f);
                        e = S(d);
                        d = T(d);
                        c.each(ma, function () {
                            if (m >= this.s.r && m <= this.e.r && b.length >= this.s.c && b.length <= this.e.c)
                                for (var a = 0; a <= this.e.c - this.s.c; ++a) b.push(null)
                        });
                        if (d || e) e = e || 1, ma.push({
                            s: {
                                r: m,
                                c: b.length
                            },
                            e: {
                                r: m + (d || 1) - 1,
                                c: b.length + e - 1
                            }
                        });
                        "function" !== typeof a.onCellData && "" !== f && f === +f && (f = +f);
                        b.push("" !== f ? f : null);
                        if (e)
                            for (d = 0; d < e - 1; ++d) b.push(null)
                    }
                });
                wa.push(b);
                m++
            });
            g = new ia;
            y = Fa(wa);
            y["!merges"] = ma;
            XLSX.utils.book_append_sheet(g, y, a.mso.worksheetName);
            g = XLSX.write(g, {
                type: "binary",
                bookType: a.mso.fileFormat,
                bookSST: !1
            });
            try {
                A = new Blob([ua(g)], {
                    type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8"
                }), saveAs(A, a.fileName +
                    "." + a.mso.fileFormat)
            } catch (b) {
                G(a.fileName + "." + a.mso.fileFormat, "data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8,", ua(g))
            }
        } else if ("excel" === a.type || "xls" === a.type || "word" === a.type || "doc" === a.type) {
            g = "excel" === a.type || "xls" === a.type ? "excel" : "word";
            y = "excel" === g ? "xls" : "doc";
            k = 'xmlns:x="urn:schemas-microsoft-com:office:' + g + '"';
            var H = "",
                Y = "";
            c(v).filter(function () {
                return Q(c(this))
            }).each(function () {
                var b = c(this);
                "" === Y && (Y = a.mso.worksheetName || b.find("caption").text() ||
                    "Table", Y = c.trim(Y.replace(/[\\\/[\]*:?'"]/g, "").substring(0, 31)));
                !1 === a.exportHiddenCells && (I = b.find("tr, th, td").filter(":hidden"), U = 0 < I.length);
                m = 0;
                F = [];
                R = P(this);
                H += "<table><thead>";
                q = b.find("thead").first().find(a.theadSelector);
                q.each(function () {
                    n = "";
                    B(this, "th,td", m, q.length, function (b, e, f) {
                        if (null !== b) {
                            var d = "";
                            n += "<th";
                            for (var l in a.mso.styles)
                                if (a.mso.styles.hasOwnProperty(l)) {
                                    var g = c(b).css(a.mso.styles[l]);
                                    "" !== g && "0px none rgb(0, 0, 0)" !== g && "rgba(0, 0, 0, 0)" !== g && (d += "" === d ? 'style="' :
                                        ";", d += a.mso.styles[l] + ":" + g)
                                }
                            "" !== d && (n += " " + d + '"');
                            d = S(b);
                            0 < d && (n += ' colspan="' + d + '"');
                            d = T(b);
                            0 < d && (n += ' rowspan="' + d + '"');
                            n += ">" + z(b, e, f) + "</th>"
                        }
                    });
                    0 < n.length && (H += "<tr>" + n + "</tr>");
                    m++
                });
                H += "</thead><tbody>";
                r = u(b);
                c(r).each(function () {
                    var b = c(this);
                    n = "";
                    B(this, "td,th", m, q.length + r.length, function (d, f, h) {
                        if (null !== d) {
                            var e = z(d, f, h),
                                g = "",
                                k = c(d).data("tableexport-msonumberformat");
                            "undefined" === typeof k && "function" === typeof a.mso.onMsoNumberFormat && (k = a.mso.onMsoNumberFormat(d, f, h));
                            "undefined" !==
                            typeof k && "" !== k && (g = "style=\"mso-number-format:'" + k + "'");
                            for (var m in a.mso.styles) a.mso.styles.hasOwnProperty(m) && (k = c(d).css(a.mso.styles[m]), "" === k && (k = b.css(a.mso.styles[m])), "" !== k && "0px none rgb(0, 0, 0)" !== k && "rgba(0, 0, 0, 0)" !== k && (g += "" === g ? 'style="' : ";", g += a.mso.styles[m] + ":" + k));
                            n += "<td";
                            "" !== g && (n += " " + g + '"');
                            f = S(d);
                            0 < f && (n += ' colspan="' + f + '"');
                            d = T(d);
                            0 < d && (n += ' rowspan="' + d + '"');
                            "string" === typeof e && "" !== e && (e = e.replace(/\n/g, "<br>"));
                            n += ">" + e + "</td>"
                        }
                    });
                    0 < n.length && (H += "<tr>" + n + "</tr>");
                    m++
                });
                a.displayTableName && (H += "<tr><td></td></tr><tr><td></td></tr><tr><td>" + z(c("<p>" + a.tableName + "</p>")) + "</td></tr>");
                H += "</tbody></table>"
            });
            k = '<html xmlns:o="urn:schemas-microsoft-com:office:office" ' + k + ' xmlns="http://www.w3.org/TR/REC-html40">' + ('<meta http-equiv="content-type" content="application/vnd.ms-' + g + '; charset=UTF-8">') + "<head>";
            "excel" === g && (k += "\x3c!--[if gte mso 9]>", k += "<xml>", k += "<x:ExcelWorkbook>", k += "<x:ExcelWorksheets>", k += "<x:ExcelWorksheet>", k += "<x:Name>", k += Y, k += "</x:Name>",
                k += "<x:WorksheetOptions>", k += "<x:DisplayGridlines/>", a.mso.rtl && (k += "<x:DisplayRightToLeft/>"), k += "</x:WorksheetOptions>", k += "</x:ExcelWorksheet>", k += "</x:ExcelWorksheets>", k += "</x:ExcelWorkbook>", k += "</xml>", k += "<![endif]--\x3e");
            k += "<style>";
            k += "@page { size:" + a.mso.pageOrientation + "; mso-page-orientation:" + a.mso.pageOrientation + "; }";
            k += "@page Section1 {size:" + L[a.mso.pageFormat][0] + "pt " + L[a.mso.pageFormat][1] + "pt";
            k += "; margin:1.0in 1.25in 1.0in 1.25in;mso-header-margin:.5in;mso-footer-margin:.5in;mso-paper-source:0;}";
            k += "div.Section1 {page:Section1;}";
            k += "@page Section2 {size:" + L[a.mso.pageFormat][1] + "pt " + L[a.mso.pageFormat][0] + "pt";
            k += ";mso-page-orientation:" + a.mso.pageOrientation + ";margin:1.25in 1.0in 1.25in 1.0in;mso-header-margin:.5in;mso-footer-margin:.5in;mso-paper-source:0;}";
            k += "div.Section2 {page:Section2;}";
            k += "br {mso-data-placement:same-cell;}";
            k += "</style>";
            k += "</head>";
            k += "<body>";
            k += '<div class="Section' + ("landscape" === a.mso.pageOrientation ? "2" : "1") + '">';
            k += H;
            k += "</div>";
            k += "</body>";
            k += "</html>";
            if ("string" === a.outputMode) return k;
            if ("base64" === a.outputMode) return J(k);
            try {
                A = new Blob([k], {
                    type: "application/vnd.ms-" + a.type
                }), saveAs(A, a.fileName + "." + y)
            } catch (b) {
                G(a.fileName + "." + y, "data:application/vnd.ms-" + g + ";base64,", k)
            }
        } else if ("png" === a.type) html2canvas(c(v)[0]).then(function (b) {
            b = b.toDataURL();
            for (var c = atob(b.substring(22)), e = new ArrayBuffer(c.length), f = new Uint8Array(e), h = 0; h < c.length; h++) f[h] = c.charCodeAt(h);
            if ("string" === a.outputMode) return c;
            if ("base64" === a.outputMode) return J(b);
            if ("window" === a.outputMode) window.open(b);
            else try {
                A = new Blob([e], {
                    type: "image/png"
                }), saveAs(A, a.fileName + ".png")
            } catch (l) {
                G(a.fileName + ".png", "data:image/png,", A)
            }
        });
        else if ("pdf" === a.type)
            if (!0 === a.pdfmake.enabled) {
                g = [];
                var xa = [];
                m = 0;
                F = [];
                y = function (a, d, e) {
                    var b = 0;
                    c(a).each(function () {
                        var a = [];
                        B(this, d, m, e, function (b, c, d) {
                            if ("undefined" !== typeof b && null !== b) {
                                var e = S(b),
                                    h = T(b);
                                b = z(b, c, d) || " ";
                                1 < e || 1 < h ? a.push({
                                    colSpan: e || 1,
                                    rowSpan: h || 1,
                                    text: b
                                }) : a.push(b)
                            } else a.push(" ")
                        });
                        a.length && xa.push(a);
                        b <
                            a.length && (b = a.length);
                        m++
                    });
                    return b
                };
                q = c(this).find("thead").first().find(a.theadSelector);
                k = y(q, "th,td", q.length);
                for (O = g.length; O < k; O++) g.push("*");
                r = u(c(this));
                y(r, "th,td", q.length + r.length);
                g = {
                    content: [{
                        table: {
                            headerRows: q.length,
                            widths: g,
                            body: xa
                        }
                    }]
                };
                c.extend(!0, g, a.pdfmake.docDefinition);
                pdfMake.fonts = {
                    Roboto: {
                        normal: "Roboto-Regular.ttf",
                        bold: "Roboto-Medium.ttf",
                        italics: "Roboto-Italic.ttf",
                        bolditalics: "Roboto-MediumItalic.ttf"
                    }
                };
                c.extend(!0, pdfMake.fonts, a.pdfmake.fonts);
                pdfMake.createPdf(g).getBuffer(function (b) {
                    try {
                        var c =
                            new Blob([b], {
                                type: "application/pdf"
                            });
                        saveAs(c, a.fileName + ".pdf")
                    } catch (e) {
                        G(a.fileName + ".pdf", "data:application/pdf;base64,", b)
                    }
                })
            } else if (!1 === a.jspdf.autotable) {
            g = {
                dim: {
                    w: ca(c(v).first().get(0), "width", "mm"),
                    h: ca(c(v).first().get(0), "height", "mm")
                },
                pagesplit: !1
            };
            var ya = new jsPDF(a.jspdf.orientation, a.jspdf.unit, a.jspdf.format);
            ya.addHTML(c(v).first(), a.jspdf.margins.left, a.jspdf.margins.top, g, function () {
                na(ya, !1)
            })
        } else {
            var f = a.jspdf.autotable.tableExport;
            if ("string" === typeof a.jspdf.format &&
                "bestfit" === a.jspdf.format.toLowerCase()) {
                var fa = "",
                    Z = "",
                    za = 0;
                c(v).each(function () {
                    if (Q(c(this))) {
                        var a = ca(c(this).get(0), "width", "pt");
                        if (a > za) {
                            a > L.a0[0] && (fa = "a0", Z = "l");
                            for (var d in L) L.hasOwnProperty(d) && L[d][1] > a && (fa = d, Z = "l", L[d][0] > a && (Z = "p"));
                            za = a
                        }
                    }
                });
                a.jspdf.format = "" === fa ? "a4" : fa;
                a.jspdf.orientation = "" === Z ? "w" : Z
            }
            if (null == f.doc && (f.doc = new jsPDF(a.jspdf.orientation, a.jspdf.unit, a.jspdf.format), "function" === typeof a.jspdf.onDocCreated)) a.jspdf.onDocCreated(f.doc);
            !0 === f.outputImages && (f.images = {});
            "undefined" !== typeof f.images && (c(v).filter(function () {
                return Q(c(this))
            }).each(function () {
                var b = 0;
                F = [];
                !1 === a.exportHiddenCells && (I = c(this).find("tr, th, td").filter(":hidden"), U = 0 < I.length);
                q = c(this).find("thead").find(a.theadSelector);
                r = u(c(this));
                c(r).each(function () {
                    B(this, "td,th", q.length + b, q.length + r.length, function (a) {
                        if ("undefined" !== typeof a && null !== a) {
                            var b = c(a).children();
                            "undefined" !== typeof b && 0 < b.length && pa(a, b, f)
                        }
                    });
                    b++
                })
            }), q = [], r = []);
            Ca(f, function () {
                c(v).filter(function () {
                    return Q(c(this))
                }).each(function () {
                    var b;
                    m = 0;
                    F = [];
                    !1 === a.exportHiddenCells && (I = c(this).find("tr, th, td").filter(":hidden"), U = 0 < I.length);
                    R = P(this);
                    f.columns = [];
                    f.rows = [];
                    f.rowoptions = {};
                    if ("function" === typeof f.onTable && !1 === f.onTable(c(this), a)) return !0;
                    a.jspdf.autotable.tableExport = null;
                    var d = c.extend(!0, {}, a.jspdf.autotable);
                    a.jspdf.autotable.tableExport = f;
                    d.margin = {};
                    c.extend(!0, d.margin, a.jspdf.margins);
                    d.tableExport = f;
                    "function" !== typeof d.beforePageContent && (d.beforePageContent = function (a) {
                        if (1 === a.pageCount) {
                            var b = a.table.rows.concat(a.table.headerRow);
                            c.each(b, function () {
                                0 < this.height && (this.height += (2 - 1.15) / 2 * this.styles.fontSize, a.table.height += (2 - 1.15) / 2 * this.styles.fontSize)
                            })
                        }
                    });
                    "function" !== typeof d.createdHeaderCell && (d.createdHeaderCell = function (a, b) {
                        a.styles = c.extend({}, b.row.styles);
                        if ("undefined" !== typeof f.columns[b.column.dataKey]) {
                            var e = f.columns[b.column.dataKey];
                            if ("undefined" !== typeof e.rect) {
                                a.contentWidth = e.rect.width;
                                if ("undefined" === typeof f.heightRatio || 0 === f.heightRatio) {
                                    var h = b.row.raw[b.column.dataKey].rowspan ? b.row.raw[b.column.dataKey].rect.height /
                                        b.row.raw[b.column.dataKey].rowspan : b.row.raw[b.column.dataKey].rect.height;
                                    f.heightRatio = a.styles.rowHeight / h
                                }
                                h = b.row.raw[b.column.dataKey].rect.height * f.heightRatio;
                                h > a.styles.rowHeight && (a.styles.rowHeight = h)
                            }
                            "undefined" !== typeof e.style && !0 !== e.style.hidden && (a.styles.halign = e.style.align, "inherit" === d.styles.fillColor && (a.styles.fillColor = e.style.bcolor), "inherit" === d.styles.textColor && (a.styles.textColor = e.style.color), "inherit" === d.styles.fontStyle && (a.styles.fontStyle = e.style.fstyle))
                        }
                    });
                    "function" !== typeof d.createdCell && (d.createdCell = function (a, b) {
                        b = f.rowoptions[b.row.index + ":" + b.column.dataKey];
                        "undefined" !== typeof b && "undefined" !== typeof b.style && !0 !== b.style.hidden && (a.styles.halign = b.style.align, "inherit" === d.styles.fillColor && (a.styles.fillColor = b.style.bcolor), "inherit" === d.styles.textColor && (a.styles.textColor = b.style.color), "inherit" === d.styles.fontStyle && (a.styles.fontStyle = b.style.fstyle))
                    });
                    "function" !== typeof d.drawHeaderCell && (d.drawHeaderCell = function (a, b) {
                        var c =
                            f.columns[b.column.dataKey];
                        return (!0 !== c.style.hasOwnProperty("hidden") || !0 !== c.style.hidden) && 0 <= c.rowIndex ? oa(a, b, c) : !1
                    });
                    "function" !== typeof d.drawCell && (d.drawCell = function (a, b) {
                        var c = f.rowoptions[b.row.index + ":" + b.column.dataKey];
                        if (oa(a, b, c))
                            if (f.doc.rect(a.x, a.y, a.width, a.height, a.styles.fillStyle), "undefined" !== typeof c && "undefined" !== typeof c.kids && 0 < c.kids.length) {
                                b = a.height / c.rect.height;
                                if (b > f.dh || "undefined" === typeof f.dh) f.dh = b;
                                f.dw = a.width / c.rect.width;
                                b = a.textPos.y;
                                ra(a, c.kids, f);
                                a.textPos.y = b;
                                sa(a, c.kids, f)
                            } else sa(a, {}, f);
                        return !1
                    });
                    f.headerrows = [];
                    q = c(this).find("thead").find(a.theadSelector);
                    q.each(function () {
                        b = 0;
                        f.headerrows[m] = [];
                        B(this, "th,td", m, q.length, function (a, c, d) {
                            var e = ta(a);
                            e.title = z(a, c, d);
                            e.key = b++;
                            e.rowIndex = m;
                            f.headerrows[m].push(e)
                        });
                        m++
                    });
                    if (0 < m)
                        for (var e = m - 1; 0 <= e;) c.each(f.headerrows[e], function () {
                                var a = this;
                                0 < e && null === this.rect && (a = f.headerrows[e - 1][this.key]);
                                null !== a && 0 <= a.rowIndex && (!0 !== a.style.hasOwnProperty("hidden") || !0 !== a.style.hidden) && f.columns.push(a)
                            }),
                            e = 0 < f.columns.length ? -1 : e - 1;
                    var g = 0;
                    r = [];
                    r = u(c(this));
                    c(r).each(function () {
                        var a = [];
                        b = 0;
                        B(this, "td,th", m, q.length + r.length, function (d, e, h) {
                            if ("undefined" === typeof f.columns[b]) {
                                var k = {
                                    title: "",
                                    key: b,
                                    style: {
                                        hidden: !0
                                    }
                                };
                                f.columns.push(k)
                            }
                            "undefined" !== typeof d && null !== d ? (k = ta(d), k.kids = c(d).children()) : (k = c.extend(!0, {}, f.rowoptions[g + ":" + (b - 1)]), k.colspan = -1);
                            f.rowoptions[g + ":" + b++] = k;
                            a.push(z(d, e, h))
                        });
                        a.length && (f.rows.push(a), g++);
                        m++
                    });
                    if ("function" === typeof f.onBeforeAutotable) f.onBeforeAutotable(c(this),
                        f.columns, f.rows, d);
                    f.doc.autoTable(f.columns, f.rows, d);
                    if ("function" === typeof f.onAfterAutotable) f.onAfterAutotable(c(this), d);
                    a.jspdf.autotable.startY = f.doc.autoTableEndPosY() + d.margin.top
                });
                na(f.doc, "undefined" !== typeof f.images && !1 === jQuery.isEmptyObject(f.images));
                "undefined" !== typeof f.headerrows && (f.headerrows.length = 0);
                "undefined" !== typeof f.columns && (f.columns.length = 0);
                "undefined" !== typeof f.rows && (f.rows.length = 0);
                delete f.doc;
                f.doc = null
            })
        }
        return this
    }
})(jQuery);

define("tableexport", ["jquery"], (function (global) {
    return function () {
        var ret, fn;
        return ret || global.$.fn.extend;
    };
}(this)));

/*
 * bootstrap-table - v1.11.1 - 2017-02-22
 * https://github.com/wenzhixin/bootstrap-table
 * Copyright (c) 2017 zhixin wen
 * Licensed MIT License
 */
! function (a) {
    "use strict";
    var b = a.fn.bootstrapTable.utils.sprintf,
        c = {
            json: "JSON",
            xml: "XML",
            png: "PNG",
            csv: "CSV",
            txt: "TXT",
            sql: "SQL",
            doc: "MS-Word",
            excel: "MS-Excel",
            xlsx: "MS-Excel (OpenXML)",
            powerpoint: "MS-Powerpoint",
            pdf: "PDF"
        };
    a.extend(a.fn.bootstrapTable.defaults, {
        showExport: !1,
        exportDataType: "basic",
        exportTypes: ["json", "xml", "csv", "txt", "sql", "excel"],
        exportOptions: {}
    }), a.extend(a.fn.bootstrapTable.defaults.icons, {
        "export": "glyphicon-export"
    }), a.extend(a.fn.bootstrapTable.locales, {
        formatExport: function () {
            return "Export data"
        }
    }), a.extend(a.fn.bootstrapTable.defaults, a.fn.bootstrapTable.locales);
    var d = a.fn.bootstrapTable.Constructor,
        e = d.prototype.initToolbar;
    d.prototype.initToolbar = function () {
        if (this.showToolbar = this.options.showExport, e.apply(this, Array.prototype.slice.apply(arguments)), this.options.showExport) {
            var d = this,
                f = this.$toolbar.find(">.btn-group"),
                g = f.find("div.export");
            if (!g.length) {
                g = a(['<div class="export btn-group">', '<button class="btn' + b(" btn-%s", this.options.buttonsClass) + b(" btn-%s", this.options.iconSize) + ' dropdown-toggle" aria-label="export type" title="' + this.options.formatExport() + '" data-toggle="dropdown" type="button">', b('<i class="%s %s"></i> ', this.options.iconsPrefix, this.options.icons["export"]), '<span class="caret"></span>', "</button>", '<ul class="dropdown-menu" role="menu">', "</ul>", "</div>"].join("")).appendTo(f);
                var h = g.find(".dropdown-menu"),
                    i = this.options.exportTypes;
                if ("string" == typeof this.options.exportTypes) {
                    var j = this.options.exportTypes.slice(1, -1).replace(/ /g, "").split(",");
                    i = [], a.each(j, function (a, b) {
                        i.push(b.slice(1, -1))
                    })
                }
                a.each(i, function (a, b) {
                    c.hasOwnProperty(b) && h.append(['<li role="menuitem" data-type="' + b + '">', '<a href="javascript:void(0)">', c[b], "</a>", "</li>"].join(""))
                }), h.find("li").click(function () {
                    var b = a(this).data("type"),
                        c = function () {
                            d.$el.tableExport(a.extend({}, d.options.exportOptions, {
                                type: b,
                                escape: !1
                            }))
                        };
                    if ("all" === d.options.exportDataType && d.options.pagination) d.$el.one("server" === d.options.sidePagination ? "post-body.bs.table" : "page-change.bs.table", function () {
                        c(), d.togglePagination()
                    }), d.togglePagination();
                    else if ("selected" === d.options.exportDataType) {
                        var e = d.getData(),
                            f = d.getAllSelections();
                        "server" === d.options.sidePagination && (e = {
                            total: d.options.totalRows
                        }, e[d.options.dataField] = d.getData(), f = {
                            total: d.options.totalRows
                        }, f[d.options.dataField] = d.getAllSelections()), d.load(f), c(), d.load(e)
                    } else c()
                })
            }
        }
    }
}(jQuery);
define("bootstrap-table-export", ["bootstrap-table", "tableexport"], (function (global) {
    return function () {
        var ret, fn;
        return ret || global.$.fn.bootstrapTable.defaults;
    };
}(this)));



(function (factory) {
    if (typeof exports === "object") {
        module.exports = factory()
    } else if (typeof define === "function" && define.amd) {
        define('spark', factory)
    } else {
        var glob;
        try {
            glob = window
        } catch (e) {
            glob = self
        }
        glob.SparkMD5 = factory()
    }
})(function (undefined) {
    "use strict";
    var add32 = function (a, b) {
            return a + b & 4294967295
        },
        hex_chr = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"];

    function cmn(q, a, b, x, s, t) {
        a = add32(add32(a, q), add32(x, t));
        return add32(a << s | a >>> 32 - s, b)
    }

    function md5cycle(x, k) {
        var a = x[0],
            b = x[1],
            c = x[2],
            d = x[3];
        a += (b & c | ~b & d) + k[0] - 680876936 | 0;
        a = (a << 7 | a >>> 25) + b | 0;
        d += (a & b | ~a & c) + k[1] - 389564586 | 0;
        d = (d << 12 | d >>> 20) + a | 0;
        c += (d & a | ~d & b) + k[2] + 606105819 | 0;
        c = (c << 17 | c >>> 15) + d | 0;
        b += (c & d | ~c & a) + k[3] - 1044525330 | 0;
        b = (b << 22 | b >>> 10) + c | 0;
        a += (b & c | ~b & d) + k[4] - 176418897 | 0;
        a = (a << 7 | a >>> 25) + b | 0;
        d += (a & b | ~a & c) + k[5] + 1200080426 | 0;
        d = (d << 12 | d >>> 20) + a | 0;
        c += (d & a | ~d & b) + k[6] - 1473231341 | 0;
        c = (c << 17 | c >>> 15) + d | 0;
        b += (c & d | ~c & a) + k[7] - 45705983 | 0;
        b = (b << 22 | b >>> 10) + c | 0;
        a += (b & c | ~b & d) + k[8] + 1770035416 | 0;
        a = (a << 7 | a >>> 25) + b | 0;
        d += (a & b | ~a & c) + k[9] - 1958414417 | 0;
        d = (d << 12 | d >>> 20) + a | 0;
        c += (d & a | ~d & b) + k[10] - 42063 | 0;
        c = (c << 17 | c >>> 15) + d | 0;
        b += (c & d | ~c & a) + k[11] - 1990404162 | 0;
        b = (b << 22 | b >>> 10) + c | 0;
        a += (b & c | ~b & d) + k[12] + 1804603682 | 0;
        a = (a << 7 | a >>> 25) + b | 0;
        d += (a & b | ~a & c) + k[13] - 40341101 | 0;
        d = (d << 12 | d >>> 20) + a | 0;
        c += (d & a | ~d & b) + k[14] - 1502002290 | 0;
        c = (c << 17 | c >>> 15) + d | 0;
        b += (c & d | ~c & a) + k[15] + 1236535329 | 0;
        b = (b << 22 | b >>> 10) + c | 0;
        a += (b & d | c & ~d) + k[1] - 165796510 | 0;
        a = (a << 5 | a >>> 27) + b | 0;
        d += (a & c | b & ~c) + k[6] - 1069501632 | 0;
        d = (d << 9 | d >>> 23) + a | 0;
        c += (d & b | a & ~b) + k[11] + 643717713 | 0;
        c = (c << 14 | c >>> 18) + d | 0;
        b += (c & a | d & ~a) + k[0] - 373897302 | 0;
        b = (b << 20 | b >>> 12) + c | 0;
        a += (b & d | c & ~d) + k[5] - 701558691 | 0;
        a = (a << 5 | a >>> 27) + b | 0;
        d += (a & c | b & ~c) + k[10] + 38016083 | 0;
        d = (d << 9 | d >>> 23) + a | 0;
        c += (d & b | a & ~b) + k[15] - 660478335 | 0;
        c = (c << 14 | c >>> 18) + d | 0;
        b += (c & a | d & ~a) + k[4] - 405537848 | 0;
        b = (b << 20 | b >>> 12) + c | 0;
        a += (b & d | c & ~d) + k[9] + 568446438 | 0;
        a = (a << 5 | a >>> 27) + b | 0;
        d += (a & c | b & ~c) + k[14] - 1019803690 | 0;
        d = (d << 9 | d >>> 23) + a | 0;
        c += (d & b | a & ~b) + k[3] - 187363961 | 0;
        c = (c << 14 | c >>> 18) + d | 0;
        b += (c & a | d & ~a) + k[8] + 1163531501 | 0;
        b = (b << 20 | b >>> 12) + c | 0;
        a += (b & d | c & ~d) + k[13] - 1444681467 | 0;
        a = (a << 5 | a >>> 27) + b | 0;
        d += (a & c | b & ~c) + k[2] - 51403784 | 0;
        d = (d << 9 | d >>> 23) + a | 0;
        c += (d & b | a & ~b) + k[7] + 1735328473 | 0;
        c = (c << 14 | c >>> 18) + d | 0;
        b += (c & a | d & ~a) + k[12] - 1926607734 | 0;
        b = (b << 20 | b >>> 12) + c | 0;
        a += (b ^ c ^ d) + k[5] - 378558 | 0;
        a = (a << 4 | a >>> 28) + b | 0;
        d += (a ^ b ^ c) + k[8] - 2022574463 | 0;
        d = (d << 11 | d >>> 21) + a | 0;
        c += (d ^ a ^ b) + k[11] + 1839030562 | 0;
        c = (c << 16 | c >>> 16) + d | 0;
        b += (c ^ d ^ a) + k[14] - 35309556 | 0;
        b = (b << 23 | b >>> 9) + c | 0;
        a += (b ^ c ^ d) + k[1] - 1530992060 | 0;
        a = (a << 4 | a >>> 28) + b | 0;
        d += (a ^ b ^ c) + k[4] + 1272893353 | 0;
        d = (d << 11 | d >>> 21) + a | 0;
        c += (d ^ a ^ b) + k[7] - 155497632 | 0;
        c = (c << 16 | c >>> 16) + d | 0;
        b += (c ^ d ^ a) + k[10] - 1094730640 | 0;
        b = (b << 23 | b >>> 9) + c | 0;
        a += (b ^ c ^ d) + k[13] + 681279174 | 0;
        a = (a << 4 | a >>> 28) + b | 0;
        d += (a ^ b ^ c) + k[0] - 358537222 | 0;
        d = (d << 11 | d >>> 21) + a | 0;
        c += (d ^ a ^ b) + k[3] - 722521979 | 0;
        c = (c << 16 | c >>> 16) + d | 0;
        b += (c ^ d ^ a) + k[6] + 76029189 | 0;
        b = (b << 23 | b >>> 9) + c | 0;
        a += (b ^ c ^ d) + k[9] - 640364487 | 0;
        a = (a << 4 | a >>> 28) + b | 0;
        d += (a ^ b ^ c) + k[12] - 421815835 | 0;
        d = (d << 11 | d >>> 21) + a | 0;
        c += (d ^ a ^ b) + k[15] + 530742520 | 0;
        c = (c << 16 | c >>> 16) + d | 0;
        b += (c ^ d ^ a) + k[2] - 995338651 | 0;
        b = (b << 23 | b >>> 9) + c | 0;
        a += (c ^ (b | ~d)) + k[0] - 198630844 | 0;
        a = (a << 6 | a >>> 26) + b | 0;
        d += (b ^ (a | ~c)) + k[7] + 1126891415 | 0;
        d = (d << 10 | d >>> 22) + a | 0;
        c += (a ^ (d | ~b)) + k[14] - 1416354905 | 0;
        c = (c << 15 | c >>> 17) + d | 0;
        b += (d ^ (c | ~a)) + k[5] - 57434055 | 0;
        b = (b << 21 | b >>> 11) + c | 0;
        a += (c ^ (b | ~d)) + k[12] + 1700485571 | 0;
        a = (a << 6 | a >>> 26) + b | 0;
        d += (b ^ (a | ~c)) + k[3] - 1894986606 | 0;
        d = (d << 10 | d >>> 22) + a | 0;
        c += (a ^ (d | ~b)) + k[10] - 1051523 | 0;
        c = (c << 15 | c >>> 17) + d | 0;
        b += (d ^ (c | ~a)) + k[1] - 2054922799 | 0;
        b = (b << 21 | b >>> 11) + c | 0;
        a += (c ^ (b | ~d)) + k[8] + 1873313359 | 0;
        a = (a << 6 | a >>> 26) + b | 0;
        d += (b ^ (a | ~c)) + k[15] - 30611744 | 0;
        d = (d << 10 | d >>> 22) + a | 0;
        c += (a ^ (d | ~b)) + k[6] - 1560198380 | 0;
        c = (c << 15 | c >>> 17) + d | 0;
        b += (d ^ (c | ~a)) + k[13] + 1309151649 | 0;
        b = (b << 21 | b >>> 11) + c | 0;
        a += (c ^ (b | ~d)) + k[4] - 145523070 | 0;
        a = (a << 6 | a >>> 26) + b | 0;
        d += (b ^ (a | ~c)) + k[11] - 1120210379 | 0;
        d = (d << 10 | d >>> 22) + a | 0;
        c += (a ^ (d | ~b)) + k[2] + 718787259 | 0;
        c = (c << 15 | c >>> 17) + d | 0;
        b += (d ^ (c | ~a)) + k[9] - 343485551 | 0;
        b = (b << 21 | b >>> 11) + c | 0;
        x[0] = a + x[0] | 0;
        x[1] = b + x[1] | 0;
        x[2] = c + x[2] | 0;
        x[3] = d + x[3] | 0
    }

    function md5blk(s) {
        var md5blks = [],
            i;
        for (i = 0; i < 64; i += 4) {
            md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) << 24)
        }
        return md5blks
    }

    function md5blk_array(a) {
        var md5blks = [],
            i;
        for (i = 0; i < 64; i += 4) {
            md5blks[i >> 2] = a[i] + (a[i + 1] << 8) + (a[i + 2] << 16) + (a[i + 3] << 24)
        }
        return md5blks
    }

    function md51(s) {
        var n = s.length,
            state = [1732584193, -271733879, -1732584194, 271733878],
            i, length, tail, tmp, lo, hi;
        for (i = 64; i <= n; i += 64) {
            md5cycle(state, md5blk(s.substring(i - 64, i)))
        }
        s = s.substring(i - 64);
        length = s.length;
        tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        for (i = 0; i < length; i += 1) {
            tail[i >> 2] |= s.charCodeAt(i) << (i % 4 << 3)
        }
        tail[i >> 2] |= 128 << (i % 4 << 3);
        if (i > 55) {
            md5cycle(state, tail);
            for (i = 0; i < 16; i += 1) {
                tail[i] = 0
            }
        }
        tmp = n * 8;
        tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
        lo = parseInt(tmp[2], 16);
        hi = parseInt(tmp[1], 16) || 0;
        tail[14] = lo;
        tail[15] = hi;
        md5cycle(state, tail);
        return state
    }

    function md51_array(a) {
        var n = a.length,
            state = [1732584193, -271733879, -1732584194, 271733878],
            i, length, tail, tmp, lo, hi;
        for (i = 64; i <= n; i += 64) {
            md5cycle(state, md5blk_array(a.subarray(i - 64, i)))
        }
        a = i - 64 < n ? a.subarray(i - 64) : new Uint8Array(0);
        length = a.length;
        tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        for (i = 0; i < length; i += 1) {
            tail[i >> 2] |= a[i] << (i % 4 << 3)
        }
        tail[i >> 2] |= 128 << (i % 4 << 3);
        if (i > 55) {
            md5cycle(state, tail);
            for (i = 0; i < 16; i += 1) {
                tail[i] = 0
            }
        }
        tmp = n * 8;
        tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
        lo = parseInt(tmp[2], 16);
        hi = parseInt(tmp[1], 16) || 0;
        tail[14] = lo;
        tail[15] = hi;
        md5cycle(state, tail);
        return state
    }

    function rhex(n) {
        var s = "",
            j;
        for (j = 0; j < 4; j += 1) {
            s += hex_chr[n >> j * 8 + 4 & 15] + hex_chr[n >> j * 8 & 15]
        }
        return s
    }

    function hex(x) {
        var i;
        for (i = 0; i < x.length; i += 1) {
            x[i] = rhex(x[i])
        }
        return x.join("")
    }
    if (hex(md51("hello")) !== "5d41402abc4b2a76b9719d911017c592") {
        add32 = function (x, y) {
            var lsw = (x & 65535) + (y & 65535),
                msw = (x >> 16) + (y >> 16) + (lsw >> 16);
            return msw << 16 | lsw & 65535
        }
    }
    if (typeof ArrayBuffer !== "undefined" && !ArrayBuffer.prototype.slice) {
        (function () {
            function clamp(val, length) {
                val = val | 0 || 0;
                if (val < 0) {
                    return Math.max(val + length, 0)
                }
                return Math.min(val, length)
            }
            ArrayBuffer.prototype.slice = function (from, to) {
                var length = this.byteLength,
                    begin = clamp(from, length),
                    end = length,
                    num, target, targetArray, sourceArray;
                if (to !== undefined) {
                    end = clamp(to, length)
                }
                if (begin > end) {
                    return new ArrayBuffer(0)
                }
                num = end - begin;
                target = new ArrayBuffer(num);
                targetArray = new Uint8Array(target);
                sourceArray = new Uint8Array(this, begin, num);
                targetArray.set(sourceArray);
                return target
            }
        })()
    }

    function toUtf8(str) {
        if (/[\u0080-\uFFFF]/.test(str)) {
            str = unescape(encodeURIComponent(str))
        }
        return str
    }

    function utf8Str2ArrayBuffer(str, returnUInt8Array) {
        var length = str.length,
            buff = new ArrayBuffer(length),
            arr = new Uint8Array(buff),
            i;
        for (i = 0; i < length; i += 1) {
            arr[i] = str.charCodeAt(i)
        }
        return returnUInt8Array ? arr : buff
    }

    function arrayBuffer2Utf8Str(buff) {
        return String.fromCharCode.apply(null, new Uint8Array(buff))
    }

    function concatenateArrayBuffers(first, second, returnUInt8Array) {
        var result = new Uint8Array(first.byteLength + second.byteLength);
        result.set(new Uint8Array(first));
        result.set(new Uint8Array(second), first.byteLength);
        return returnUInt8Array ? result : result.buffer
    }

    function hexToBinaryString(hex) {
        var bytes = [],
            length = hex.length,
            x;
        for (x = 0; x < length - 1; x += 2) {
            bytes.push(parseInt(hex.substr(x, 2), 16))
        }
        return String.fromCharCode.apply(String, bytes)
    }

    function SparkMD5() {
        this.reset()
    }
    SparkMD5.prototype.append = function (str) {
        this.appendBinary(toUtf8(str));
        return this
    };
    SparkMD5.prototype.appendBinary = function (contents) {
        this._buff += contents;
        this._length += contents.length;
        var length = this._buff.length,
            i;
        for (i = 64; i <= length; i += 64) {
            md5cycle(this._hash, md5blk(this._buff.substring(i - 64, i)))
        }
        this._buff = this._buff.substring(i - 64);
        return this
    };
    SparkMD5.prototype.end = function (raw) {
        var buff = this._buff,
            length = buff.length,
            i, tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            ret;
        for (i = 0; i < length; i += 1) {
            tail[i >> 2] |= buff.charCodeAt(i) << (i % 4 << 3)
        }
        this._finish(tail, length);
        ret = hex(this._hash);
        if (raw) {
            ret = hexToBinaryString(ret)
        }
        this.reset();
        return ret
    };
    SparkMD5.prototype.reset = function () {
        this._buff = "";
        this._length = 0;
        this._hash = [1732584193, -271733879, -1732584194, 271733878];
        return this
    };
    SparkMD5.prototype.getState = function () {
        return {
            buff: this._buff,
            length: this._length,
            hash: this._hash
        }
    };
    SparkMD5.prototype.setState = function (state) {
        this._buff = state.buff;
        this._length = state.length;
        this._hash = state.hash;
        return this
    };
    SparkMD5.prototype.destroy = function () {
        delete this._hash;
        delete this._buff;
        delete this._length
    };
    SparkMD5.prototype._finish = function (tail, length) {
        var i = length,
            tmp, lo, hi;
        tail[i >> 2] |= 128 << (i % 4 << 3);
        if (i > 55) {
            md5cycle(this._hash, tail);
            for (i = 0; i < 16; i += 1) {
                tail[i] = 0
            }
        }
        tmp = this._length * 8;
        tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
        lo = parseInt(tmp[2], 16);
        hi = parseInt(tmp[1], 16) || 0;
        tail[14] = lo;
        tail[15] = hi;
        md5cycle(this._hash, tail)
    };
    SparkMD5.hash = function (str, raw) {
        return SparkMD5.hashBinary(toUtf8(str), raw)
    };
    SparkMD5.hashBinary = function (content, raw) {
        var hash = md51(content),
            ret = hex(hash);
        return raw ? hexToBinaryString(ret) : ret
    };
    SparkMD5.ArrayBuffer = function () {
        this.reset()
    };
    SparkMD5.ArrayBuffer.prototype.append = function (arr) {
        var buff = concatenateArrayBuffers(this._buff.buffer, arr, true),
            length = buff.length,
            i;
        this._length += arr.byteLength;
        for (i = 64; i <= length; i += 64) {
            md5cycle(this._hash, md5blk_array(buff.subarray(i - 64, i)))
        }
        this._buff = i - 64 < length ? new Uint8Array(buff.buffer.slice(i - 64)) : new Uint8Array(0);
        return this
    };
    SparkMD5.ArrayBuffer.prototype.end = function (raw) {
        var buff = this._buff,
            length = buff.length,
            tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            i, ret;
        for (i = 0; i < length; i += 1) {
            tail[i >> 2] |= buff[i] << (i % 4 << 3)
        }
        this._finish(tail, length);
        ret = hex(this._hash);
        if (raw) {
            ret = hexToBinaryString(ret)
        }
        this.reset();
        return ret
    };
    SparkMD5.ArrayBuffer.prototype.reset = function () {
        this._buff = new Uint8Array(0);
        this._length = 0;
        this._hash = [1732584193, -271733879, -1732584194, 271733878];
        return this
    };
    SparkMD5.ArrayBuffer.prototype.getState = function () {
        var state = SparkMD5.prototype.getState.call(this);
        state.buff = arrayBuffer2Utf8Str(state.buff);
        return state
    };
    SparkMD5.ArrayBuffer.prototype.setState = function (state) {
        state.buff = utf8Str2ArrayBuffer(state.buff, true);
        return SparkMD5.prototype.setState.call(this, state)
    };
    SparkMD5.ArrayBuffer.prototype.destroy = SparkMD5.prototype.destroy;
    SparkMD5.ArrayBuffer.prototype._finish = SparkMD5.prototype._finish;
    SparkMD5.ArrayBuffer.hash = function (arr, raw) {
        var hash = md51_array(new Uint8Array(arr)),
            ret = hex(hash);
        return raw ? hexToBinaryString(ret) : ret
    };
    return SparkMD5
});


/*! nice-validator 1.1.4
 * (c) 2012-2018 Jony Zhang <niceue@live.com>, MIT Licensed
 * https://github.com/niceue/nice-validator
 */
;
(function (factory) {
    typeof module === 'object' && module.exports ? module.exports = factory(require('jquery')) :
        typeof define === 'function' && define.amd ? define('validator-core', ['jquery'], factory) :
        factory(jQuery);
}(function ($, undefined) {
    'use strict';

    var NS = 'validator',
        CLS_NS = '.' + NS,
        CLS_NS_RULE = '.rule',
        CLS_NS_FIELD = '.field',
        CLS_NS_FORM = '.form',
        CLS_WRAPPER = 'nice-' + NS,
        CLS_MSG_BOX = 'msg-box',
        ARIA_INVALID = 'aria-invalid',
        DATA_RULE = 'data-rule',
        DATA_MSG = 'data-msg',
        DATA_TIP = 'data-tip',
        DATA_OK = 'data-ok',
        DATA_TIMELY = 'data-timely',
        DATA_TARGET = 'data-target',
        DATA_DISPLAY = 'data-display',
        DATA_MUST = 'data-must',
        NOVALIDATE = 'novalidate',
        INPUT_SELECTOR = ':verifiable',

        rRules = /(&)?(!)?\b(\w+)(?:\[\s*(.*?\]?)\s*\]|\(\s*(.*?\)?)\s*\))?\s*(;|\|)?/g,
        rRule = /(\w+)(?:\[\s*(.*?\]?)\s*\]|\(\s*(.*?\)?)\s*\))?/,
        rDisplay = /(?:([^:;\(\[]*):)?(.*)/,
        rDoubleBytes = /[^\x00-\xff]/g,
        rPos = /top|right|bottom|left/,
        rAjaxType = /(?:(cors|jsonp):)?(?:(post|get):)?(.+)/i,
        rUnsafe = /[<>'"`\\]|&#x?\d+[A-F]?;?|%3[A-F]/gmi,

        noop = $.noop,
        proxy = $.proxy,
        trim = $.trim,
        isFunction = $.isFunction,
        isString = function (s) {
            return typeof s === 'string';
        },
        isObject = function (o) {
            return o && Object.prototype.toString.call(o) === '[object Object]';
        },
        isIE = document.documentMode || +(navigator.userAgent.match(/MSIE (\d+)/) && RegExp.$1),
        attr = function (el, key, value) {
            if (!el || !el.tagName) return null;
            if (value !== undefined) {
                if (value === null) el.removeAttribute(key);
                else el.setAttribute(key, '' + value);
            } else {
                return el.getAttribute(key);
            }
        },
        novalidateonce,
        preinitialized = {},

        defaults = {
            debug: 0,
            theme: 'default',
            ignore: '',
            focusInvalid: true,
            focusCleanup: false,
            stopOnError: false,
            beforeSubmit: null,
            valid: null,
            invalid: null,
            validation: null,
            formClass: 'n-default',
            validClass: 'n-valid',
            invalidClass: 'n-invalid',
            bindClassTo: null
        },
        fieldDefaults = {
            timely: 1,
            display: null,
            target: null,
            ignoreBlank: false,
            showOk: true,
            // Translate ajax response to validation result
            dataFilter: function (data) {
                if (isString(data) || (isObject(data) && ('error' in data || 'ok' in data))) {
                    return data;
                }
            },
            msgMaker: function (opt) {
                var html;
                html = '<span role="alert" class="msg-wrap n-' + opt.type + '">' + opt.arrow;
                if (opt.result) {
                    $.each(opt.result, function (i, obj) {
                        html += '<span class="n-' + obj.type + '">' + opt.icon + '<span class="n-msg">' + obj.msg + '</span></span>';
                    });
                } else {
                    html += opt.icon + '<span class="n-msg">' + opt.msg + '</span>';
                }
                html += '</span>';
                return html;
            },
            msgWrapper: 'span',
            msgArrow: '',
            msgIcon: '<span class="n-icon"></span>',
            msgClass: 'n-right',
            msgStyle: '',
            msgShow: null,
            msgHide: null
        },
        themes = {};

    /** jQuery Plugin
     * @param {Object} options
        debug         {Boolean}     0               Whether to enable debug mode
        timely        {Number}      1               Whether to enable timely validation
        theme         {String}     'default'        Theme name
        stopOnError   {Boolean}     false           Whether to stop validate when found an error input
        focusCleanup  {Boolean}     false           Whether to clean up the field message when focus the field
        focusInvalid  {Boolean}     true            Whether to focus the field that is invalid
        ignoreBlank   {Boolean}     false           When the field has no value, whether to ignore validation
        ignore        {jqSelector}    ''            Ignored fields (Using jQuery selector)

        beforeSubmit  {Function}                    Do something before submit form
        dataFilter    {Function}                    Convert ajax results
        valid         {Function}                    Triggered when the form is valid
        invalid       {Function}                    Triggered when the form is invalid
        validClass    {String}      'n-valid'       Add this class name to a valid field
        invalidClass  {String}      'n-invalid'     Add this class name to a invalid field
        bindClassTo   {jqSelector}  ':verifiable'   Which element should the className binding to

        display       {Function}                    Callback function to get dynamic display
        target        {Function}                    Callback function to get dynamic target
        msgShow       {Function}                    Trigger this callback when show message
        msgHide       {Function}                    Trigger this callback when hide message
        msgWrapper    {String}      'span'          Message wrapper tag name
        msgMaker      {Function}                    Callback function to make message HTML
        msgArrow      {String}                      Message arrow template
        msgIcon       {String}                      Message icon template
        msgStyle      {String}                      Custom message css style
        msgClass      {String}                      Additional added to the message class names
        formClass     {String}                      Additional added to the form class names

        messages      {Object}                      Custom messages for the current instance
        rules         {Object}                      Custom rules for the current instance
        fields        {Object}                      Field validation configuration
        {String}        key    name|#id
        {String|Object} value                       Rule string or an object which can pass more arguments

        fields[key][rule]       {String}            Rule string
        fields[key][display]    {String|Function}
        fields[key][tip]        {String}            Custom tip message
        fields[key][ok]         {String}            Custom success message
        fields[key][msg]        {Object}            Custom error message
        fields[key][msgStyle]   {String}            Custom message style
        fields[key][msgClass]   {String}            A className which added to message placeholder element
        fields[key][msgWrapper] {String}            Tag name of the message placeholder element
        fields[key][msgMaker]   {Function}          A function to custom message HTML
        fields[key][dataFilter] {Function}          A function to convert ajax results
        fields[key][valid]      {Function}          A function triggered when field is valid
        fields[key][invalid]    {Function}          A function triggered when field is invalid
        fields[key][must]       {Boolean}           If set true, we always check the field even has remote checking
        fields[key][timely]     {Boolean}           Whether to enable timely validation
        fields[key][target]     {jqSelector}        Define placement of a message
     */
    $.fn.validator = function (options) {
        var that = this,
            args = arguments;

        if (that.is(INPUT_SELECTOR)) return that;
        if (!that.is('form')) that = this.find('form');
        if (!that.length) that = this;

        that.each(function () {
            var instance = $(this).data(NS);

            if (instance) {
                if (isString(options)) {
                    if (options.charAt(0) === '_') return;
                    instance[options].apply(instance, [].slice.call(args, 1));
                } else if (options) {
                    instance._reset(true);
                    instance._init(this, options);
                }
            } else {
                new Validator(this, options);
            }
        });

        return this;
    };


    // Validate a field, or an area
    $.fn.isValid = function (callback, hideMsg) {
        var me = _getInstance(this[0]),
            hasCallback = isFunction(callback),
            ret, opt;

        if (!me) return true;
        if (!hasCallback && hideMsg === undefined) hideMsg = callback;
        me.checkOnly = !!hideMsg;
        opt = me.options;

        ret = me._multiValidate(
            this.is(INPUT_SELECTOR) ? this : this.find(INPUT_SELECTOR),
            function (isValid) {
                if (!isValid && opt.focusInvalid && !me.checkOnly) {
                    // navigate to the error element
                    me.$el.find('[' + ARIA_INVALID + ']:first').focus();
                }
                if (hasCallback) {
                    if (callback.length) {
                        callback(isValid);
                    } else if (isValid) {
                        callback();
                    }
                }
                me.checkOnly = false;
            }
        );

        // If you pass a callback, we maintain the jQuery object chain
        return hasCallback ? this : ret;
    };

    $.extend($.expr.pseudos || $.expr[':'], {
        // A faster selector than ":input:not(:submit,:button,:reset,:image,:disabled,[contenteditable])"
        verifiable: function (elem) {
            var name = elem.nodeName.toLowerCase();

            return (name === 'input' && !({
                    submit: 1,
                    button: 1,
                    reset: 1,
                    image: 1
                })[elem.type] ||
                name === 'select' ||
                name === 'textarea' ||
                elem.contentEditable === 'true'
            ) && !elem.disabled;
        },
        // any value, but not only whitespace
        filled: function (elem) {
            return !!trim($(elem).val());
        }
    });

    /**
     * Creates a new Validator
     *
     * @class
     * @param {Element} element - form element
     * @param {Object}  options - options for validator
     */
    function Validator(element, options) {
        var me = this;

        if (!(me instanceof Validator)) {
            return new Validator(element, options);
        }

        if (Validator.pending) {
            $(window).on('validatorready', init);
        } else {
            init();
        }

        function init() {
            me.$el = $(element);
            if (me.$el.length) {
                me._init(me.$el[0], options);
            } else if (isString(element)) {
                preinitialized[element] = options;
            }
        }
    }

    Validator.prototype = {
        _init: function (element, options) {
            var me = this,
                opt, themeOpt, dataOpt;

            // Initialization options
            if (isFunction(options)) {
                options = {
                    valid: options
                };
            }
            options = me._opt = options || {};
            dataOpt = attr(element, 'data-' + NS + '-option');
            dataOpt = me._dataOpt = dataOpt && dataOpt.charAt(0) === '{' ? (new Function('return ' + dataOpt))() : {};
            themeOpt = me._themeOpt = themes[options.theme || dataOpt.theme || defaults.theme];
            opt = me.options = $.extend({}, defaults, fieldDefaults, themeOpt, me.options, options, dataOpt);

            me.rules = new Rules(opt.rules, true);
            me.messages = new Messages(opt.messages, true);
            me.Field = _createFieldFactory(me);
            me.elements = me.elements || {};
            me.deferred = {};
            me.errors = {};
            me.fields = {};
            // Initialization fields
            me._initFields(opt.fields);

            // Initialization events and make a cache
            if (!me.$el.data(NS)) {
                me.$el.data(NS, me).addClass(CLS_WRAPPER + ' ' + opt.formClass)
                    .on('form-submit-validate', function (e, a, $form, opts, veto) {
                        me.vetoed = veto.veto = !me.isValid;
                        me.ajaxFormOptions = opts;
                    })
                    .on('submit' + CLS_NS + ' validate' + CLS_NS, proxy(me, '_submit'))
                    .on('reset' + CLS_NS, proxy(me, '_reset'))
                    .on('showmsg' + CLS_NS, proxy(me, '_showmsg'))
                    .on('hidemsg' + CLS_NS, proxy(me, '_hidemsg'))
                    .on('focusin' + CLS_NS + ' click' + CLS_NS, INPUT_SELECTOR, proxy(me, '_focusin'))
                    .on('focusout' + CLS_NS + ' validate' + CLS_NS, INPUT_SELECTOR, proxy(me, '_focusout'))
                    .on('keyup' + CLS_NS + ' input' + CLS_NS + ' compositionstart compositionend', INPUT_SELECTOR, proxy(me, '_focusout'))
                    .on('click' + CLS_NS, ':radio,:checkbox', 'click', proxy(me, '_focusout'))
                    .on('change' + CLS_NS, 'select,input[type="file"]', 'change', proxy(me, '_focusout'));

                // cache the novalidate attribute value
                me._NOVALIDATE = attr(element, NOVALIDATE);
                // Initialization is complete, stop off default HTML5 form validation
                // If use "jQuery.attr('novalidate')" in IE7 will complain: "SCRIPT3: Member not found."
                attr(element, NOVALIDATE, NOVALIDATE);
            }

            // Display all messages in target container
            if (isString(opt.target)) {
                me.$el.find(opt.target).addClass('msg-container');
            }
        },

        // Guess whether the form use ajax submit
        _guessAjax: function (form) {
            var me = this;

            if (!(me.isAjaxSubmit = !!me.options.valid)) {
                // if there is a "valid.form" event
                var events = ($._data || $.data)(form, 'events');
                me.isAjaxSubmit = issetEvent(events, 'valid', 'form') || issetEvent(events, 'submit', 'form-plugin');
            }

            function issetEvent(events, name, namespace) {
                return !!(
                    events && events[name] &&
                    $.map(events[name], function (e) {
                        return ~e.namespace.indexOf(namespace) ? 1 : null;
                    }).length)
            }
        },

        _initFields: function (fields) {
            var me = this,
                k, arr, i,
                clear = fields === null;

            // Processing field information
            if (clear) fields = me.fields;

            if (isObject(fields)) {
                for (k in fields) {
                    if (~k.indexOf(',')) {
                        arr = k.split(',');
                        i = arr.length;
                        while (i--) {
                            initField(trim(arr[i]), fields[k]);
                        }
                    } else {
                        initField(k, fields[k]);
                    }
                }
            }

            // Parsing DOM rules
            me.$el.find(INPUT_SELECTOR).each(function () {
                me._parse(this);
            });

            function initField(k, v) {
                // delete a field from settings
                if (v === null || clear) {
                    var el = me.elements[k];
                    if (el) me._resetElement(el, true);
                    delete me.fields[k];
                } else {
                    me.fields[k] = new me.Field(k, isString(v) ? {
                        rule: v
                    } : v, me.fields[k]);
                }
            }
        },

        // Parsing a field
        _parse: function (el) {
            var me = this,
                field,
                key = el.name,
                display,
                timely,
                dataRule = attr(el, DATA_RULE);

            dataRule && attr(el, DATA_RULE, null);

            // If the field has passed the key as id mode, or it doesn't has a name
            if (el.id && (
                    ('#' + el.id in me.fields) ||
                    !key ||
                    // If dataRule and element are diffrent from old's, we use ID mode.
                    (dataRule !== null && (field = me.fields[key]) && dataRule !== field.rule && el.id !== field.key)
                )) {
                key = '#' + el.id;
            }
            // Generate id
            if (!key) {
                key = '#' + (el.id = 'N' + String(Math.random()).slice(-12));
            }

            field = me.getField(key, true);
            // The priority of passing parameter by DOM is higher than by JS.
            field.rule = dataRule || field.rule;

            if (display = attr(el, DATA_DISPLAY)) {
                field.display = display;
            }
            if (field.rule) {
                if (attr(el, DATA_MUST) !== null || /\b(?:match|checked)\b/.test(field.rule)) {
                    field.must = true;
                }
                if (/\brequired\b/.test(field.rule)) {
                    field.required = true;
                }
                if (timely = attr(el, DATA_TIMELY)) {
                    field.timely = +timely;
                } else if (field.timely > 3) {
                    attr(el, DATA_TIMELY, field.timely);
                }
                me._parseRule(field);
                field.old = {};
            }
            if (isString(field.target)) {
                attr(el, DATA_TARGET, field.target);
            }
            if (isString(field.tip)) {
                attr(el, DATA_TIP, field.tip);
            }

            return me.fields[key] = field;
        },

        // Parsing field rules
        _parseRule: function (field) {
            var arr = rDisplay.exec(field.rule);

            if (!arr) return;
            // current rule index
            field._i = 0;
            if (arr[1]) {
                field.display = arr[1];
            }
            if (arr[2]) {
                field._rules = [];
                arr[2].replace(rRules, function () {
                    var args = arguments;
                    args[4] = args[4] || args[5];
                    field._rules.push({
                        and: args[1] === '&',
                        not: args[2] === '!',
                        or: args[6] === '|',
                        method: args[3],
                        params: args[4] ? $.map(args[4].split(', '), trim) : undefined
                    });
                });
            }
        },

        // Verify a zone
        _multiValidate: function ($inputs, doneCallback) {
            var me = this,
                opt = me.options;

            me.hasError = false;

            if (opt.ignore) {
                $inputs = $inputs.not(opt.ignore);
            }

            $inputs.each(function () {
                me._validate(this);
                if (me.hasError && opt.stopOnError) {
                    // stop the validation
                    return false;
                }
            });

            // Need to wait for all fields validation complete, especially asynchronous validation
            if (doneCallback) {
                me.validating = true;
                $.when.apply(
                    null,
                    $.map(me.deferred, function (v) {
                        return v;
                    })
                ).done(function () {
                    doneCallback.call(me, !me.hasError);
                    me.validating = false;
                });
            }

            // If the form does not contain asynchronous validation, the return value is correct.
            // Otherwise, you should detect form validation result through "doneCallback".
            return !$.isEmptyObject(me.deferred) ? undefined : !me.hasError;
        },

        // Validate the whole form
        _submit: function (e) {
            var me = this,
                opt = me.options,
                form = e.target,
                canSubmit = e.type === 'submit' && form.tagName === 'FORM' && !e.isDefaultPrevented();

            e.preventDefault();

            if (
                novalidateonce && ~(novalidateonce = false) ||
                // Prevent duplicate submission
                me.submiting ||
                // Receive the "validate" event only from the form.
                e.type === 'validate' && me.$el[0] !== form ||
                // trigger the beforeSubmit callback.
                isFunction(opt.beforeSubmit) && opt.beforeSubmit.call(me, form) === false
            ) {
                return;
            }

            if (me.isAjaxSubmit === undefined) {
                me._guessAjax(form);
            }

            me._debug('log', '\n<<< event: ' + e.type);

            me._reset();
            me.submiting = true;

            me._multiValidate(
                me.$el.find(INPUT_SELECTOR),
                function (isValid) {
                    var ret = (isValid || opt.debug === 2) ? 'valid' : 'invalid',
                        errors;

                    if (!isValid) {
                        if (opt.focusInvalid) {
                            // navigate to the error element
                            me.$el.find('[' + ARIA_INVALID + ']:first').focus();
                        }
                        errors = $.map(me.errors, function (err) {
                            return err;
                        });
                    }

                    // releasing submit
                    me.submiting = false;
                    me.isValid = isValid;

                    // trigger callback and event
                    isFunction(opt[ret]) && opt[ret].call(me, form, errors);
                    me.$el.trigger(ret + CLS_NS_FORM, [form, errors]);

                    me._debug('log', '>>> ' + ret);

                    if (!isValid) return;
                    // For jquery.form plugin
                    if (me.vetoed) {
                        $(form).ajaxSubmit(me.ajaxFormOptions);
                    } else if (canSubmit && !me.isAjaxSubmit) {
                        document.createElement('form').submit.call(form);
                    }
                }
            );
        },

        _reset: function (e) {
            var me = this;

            me.errors = {};
            if (e) {
                me.reseting = true;
                me.$el.find(INPUT_SELECTOR).each(function () {
                    me._resetElement(this);
                });
                delete me.reseting;
            }
        },

        _resetElement: function (el, all) {
            this._setClass(el, null);
            this.hideMsg(el);
        },

        // Handle events: "focusin/click"
        _focusin: function (e) {
            var me = this,
                opt = me.options,
                el = e.target,
                timely,
                msg;

            if (me.validating || (e.type === 'click' && document.activeElement === el)) {
                return;
            }

            if (opt.focusCleanup) {
                if (attr(el, ARIA_INVALID) === 'true') {
                    me._setClass(el, null);
                    me.hideMsg(el);
                }
            }

            msg = attr(el, DATA_TIP);

            if (msg) {
                me.showMsg(el, {
                    type: 'tip',
                    msg: msg
                });
            } else {
                if (attr(el, DATA_RULE)) {
                    me._parse(el);
                }
                if (timely = attr(el, DATA_TIMELY)) {
                    if (timely === 8 || timely === 9) {
                        me._focusout(e);
                    }
                }
            }
        },

        // Handle events: "focusout/validate/keyup/click/change/input/compositionstart/compositionend"
        _focusout: function (e) {
            var me = this,
                opt = me.options,
                el = e.target,
                etype = e.type,
                etype0,
                focusin = etype === 'focusin',
                special = etype === 'validate',
                elem,
                field,
                old,
                value,
                timestamp,
                key, specialKey,
                timely,
                timer = 0;

            if (etype === 'compositionstart') {
                me.pauseValidate = true;
            }
            if (etype === 'compositionend') {
                me.pauseValidate = false;
            }
            if (me.pauseValidate) {
                return;
            }

            // For checkbox and radio
            elem = el.name && _checkable(el) ? me.$el.find('input[name="' + el.name + '"]').get(0) : el;
            // Get field
            if (!(field = me.getField(elem)) || !field.rule) {
                return;
            }
            // Cache event type
            etype0 = field._e;
            field._e = etype;
            timely = field.timely;

            if (!special) {
                if (!timely || (_checkable(el) && etype !== 'click')) {
                    return;
                }

                value = field.getValue();

                // not validate field unless fill a value
                if (field.ignoreBlank && !value && !focusin) {
                    me.hideMsg(el);
                    return;
                }

                if (etype === 'focusout') {
                    if (etype0 === 'change') {
                        return;
                    }
                    if (timely === 2 || timely === 8) {
                        old = field.old;
                        if (value && old) {
                            if (field.isValid && !old.showOk) {
                                me.hideMsg(el);
                            } else {
                                me._makeMsg(el, field, old);
                            }
                        } else {
                            return;
                        }
                    }
                } else {
                    if (timely < 2 && !e.data) {
                        return;
                    }

                    // mark timestamp to reduce the frequency of the received event
                    timestamp = +new Date();
                    if (timestamp - (el._ts || 0) < 100) {
                        return;
                    }
                    el._ts = timestamp;

                    // handle keyup
                    if (etype === 'keyup') {
                        if (etype0 === 'input') {
                            return;
                        }
                        key = e.keyCode;
                        specialKey = {
                            8: 1, // Backspace
                            9: 1, // Tab
                            16: 1, // Shift
                            32: 1, // Space
                            46: 1 // Delete
                        };

                        // only gets focus, no validation
                        if (key === 9 && !value) {
                            return;
                        }

                        // do not validate, if triggered by these keys
                        if (key < 48 && !specialKey[key]) {
                            return;
                        }
                    }
                    if (!focusin) {
                        // keyboard events, reducing the frequency of validation
                        timer = timely < 100 ? (etype === 'click' || el.tagName === 'SELECT') ? 0 : 400 : timely;
                    }
                }
            }

            // if the current field is ignored
            if (opt.ignore && $(el).is(opt.ignore)) {
                return;
            }

            clearTimeout(field._t);

            if (timer) {
                field._t = setTimeout(function () {
                    me._validate(el, field);
                }, timer);
            } else {
                if (special) field.old = {};
                me._validate(el, field);
            }
        },

        _setClass: function (el, isValid) {
            var $el = $(el),
                opt = this.options;
            if (opt.bindClassTo) {
                $el = $el.closest(opt.bindClassTo);
            }
            $el.removeClass(opt.invalidClass + ' ' + opt.validClass);
            if (isValid !== null) {
                $el.addClass(isValid ? opt.validClass : opt.invalidClass);
            }
        },

        _showmsg: function (e, type, msg) {
            var me = this,
                el = e.target;

            if (me.$el.is(el)) {
                if (isObject(type)) {
                    me.showMsg(type)
                } else if (type === 'tip') {
                    me.$el.find(INPUT_SELECTOR + '[' + DATA_TIP + ']', el).each(function () {
                        me.showMsg(this, {
                            type: type,
                            msg: msg
                        });
                    });
                }
            } else {
                me.showMsg(el, {
                    type: type,
                    msg: msg
                });
            }
        },

        _hidemsg: function (e) {
            var $el = $(e.target);

            if ($el.is(INPUT_SELECTOR)) {
                this.hideMsg($el);
            }
        },

        // Validated a field
        _validatedField: function (el, field, ret) {
            var me = this,
                opt = me.options,
                isValid = field.isValid = ret.isValid = !!ret.isValid,
                callback = isValid ? 'valid' : 'invalid';

            ret.key = field.key;
            ret.ruleName = field._r;
            ret.id = el.id;
            ret.value = field.value;

            me.elements[field.key] = ret.element = el;
            me.isValid = me.$el[0].isValid = isValid ? me.isFormValid() : isValid;

            if (isValid) {
                ret.type = 'ok';
            } else {
                if (me.submiting) {
                    me.errors[field.key] = ret.msg;
                }
                me.hasError = true;
            }

            // cache result
            field.old = ret;

            // trigger callback
            isFunction(field[callback]) && field[callback].call(me, el, ret);
            isFunction(opt.validation) && opt.validation.call(me, el, ret);

            // trigger event
            $(el).attr(ARIA_INVALID, isValid ? null : true)
                .trigger(callback + CLS_NS_FIELD, [ret, me]);
            me.$el.triggerHandler('validation', [ret, me]);

            if (me.checkOnly) return;
            // set className
            me._setClass(el, ret.skip || ret.type === 'tip' ? null : isValid);
            me._makeMsg.apply(me, arguments);
        },

        _makeMsg: function (el, field, ret) {
            // show or hide the message
            if (field.msgMaker) {
                ret = $.extend({}, ret);
                if (field._e === 'focusin') {
                    ret.type = 'tip';
                }
                this[ret.showOk || ret.msg || ret.type === 'tip' ? 'showMsg' : 'hideMsg'](el, ret, field);
            }
        },

        // Validated a rule
        _validatedRule: function (el, field, ret, msgOpt) {
            field = field || me.getField(el);
            msgOpt = msgOpt || {};

            var me = this,
                msg,
                rule,
                method = field._r,
                timely = field.timely,
                special = timely === 9 || timely === 8,
                transfer,
                temp,
                isValid = false;

            // use null to break validation from a field
            if (ret === null) {
                me._validatedField(el, field, {
                    isValid: true,
                    skip: true
                });
                field._i = 0;
                return;
            } else if (ret === undefined) {
                transfer = true;
            } else if (ret === true || ret === '') {
                isValid = true;
            } else if (isString(ret)) {
                msg = ret;
            } else if (isObject(ret)) {
                if (ret.error) {
                    msg = ret.error;
                } else {
                    msg = ret.ok;
                    isValid = true;
                }
            } else {
                isValid = !!ret
            }

            rule = field._rules[field._i];
            if (rule.not) {
                msg = undefined;
                isValid = method === 'required' || !isValid;
            }
            if (rule.or) {
                if (isValid) {
                    while (field._i < field._rules.length && field._rules[field._i].or) {
                        field._i++;
                    }
                } else {
                    transfer = true;
                }
            } else if (rule.and) {
                if (!field.isValid) transfer = true;
            }

            if (transfer) {
                isValid = true;
            }
            // message analysis, and throw rule level event
            else {
                if (isValid) {
                    if (field.showOk !== false) {
                        temp = attr(el, DATA_OK);
                        msg = temp === null ? isString(field.ok) ? field.ok : msg : temp;
                        if (!isString(msg) && isString(field.showOk)) {
                            msg = field.showOk;
                        }
                        if (isString(msg)) {
                            msgOpt.showOk = isValid;
                        }
                    }
                }
                if (!isValid || special) {
                    /* rule message priority:
                        1. custom DOM message
                        2. custom field message;
                        3. global defined message;
                        4. rule returned message;
                        5. default message;
                    */
                    msg = (_getDataMsg(el, field, msg || rule.msg || me.messages[method]) || me.messages.fallback).replace(/\{0\|?([^\}]*)\}/, function (m, defaultDisplay) {
                        return me._getDisplay(el, field.display) || defaultDisplay || me.messages[0];
                    });
                }
                if (!isValid) field.isValid = isValid;
                msgOpt.msg = msg;
                $(el).trigger((isValid ? 'valid' : 'invalid') + CLS_NS_RULE, [method, msg]);
            }

            if (special && (!transfer || rule.and)) {
                if (!isValid && !field._m) field._m = msg;
                field._v = field._v || [];
                field._v.push({
                    type: isValid ? !transfer ? 'ok' : 'tip' : 'error',
                    msg: msg || rule.msg
                });
            }

            me._debug('log', '   ' + field._i + ': ' + method + ' => ' + (isValid || msg));

            // the current rule has passed, continue to validate
            if ((isValid || special) && field._i < field._rules.length - 1) {
                field._i++;
                me._checkRule(el, field);
            }
            // field was invalid, or all fields was valid
            else {
                field._i = 0;

                if (special) {
                    msgOpt.isValid = field.isValid;
                    msgOpt.result = field._v;
                    msgOpt.msg = field._m || '';
                    if (!field.value && (field._e === 'focusin')) {
                        msgOpt.type = 'tip';
                    }
                } else {
                    msgOpt.isValid = isValid;
                }

                me._validatedField(el, field, msgOpt);
                delete field._m;
                delete field._v;
            }
        },

        // Verify a rule form a field
        _checkRule: function (el, field) {
            var me = this,
                ret,
                fn,
                old,
                key = field.key,
                rule = field._rules[field._i],
                method = rule.method,
                params = rule.params;

            // request has been sent, wait it
            if (me.submiting && me.deferred[key]) {
                return;
            }
            old = field.old;
            field._r = method;

            if (old && !field.must && !rule.must && rule.result !== undefined &&
                old.ruleName === method && old.id === el.id &&
                field.value && old.value === field.value) {
                // get result from cache
                ret = rule.result;
            } else {
                // get result from current rule
                fn = _getDataRule(el, method) || me.rules[method] || noop;
                ret = fn.call(field, el, params, field);
                if (fn.msg) rule.msg = fn.msg;
            }

            // asynchronous validation
            if (isObject(ret) && isFunction(ret.then)) {
                me.deferred[key] = ret;

                // whether the field valid is unknown
                field.isValid = undefined;

                // show loading message
                !me.checkOnly && me.showMsg(el, {
                    type: 'loading',
                    msg: me.messages.loading
                }, field);

                // waiting to parse the response data
                ret.then(
                    function (d, textStatus, jqXHR) {
                        var data = trim(jqXHR.responseText),
                            result,
                            dataFilter = field.dataFilter;

                        // detect if data is json or jsonp format
                        if (/jsonp?/.test(this.dataType)) {
                            data = d;
                        } else if (data.charAt(0) === '{') {
                            data = $.parseJSON(data);
                        }

                        // filter data
                        result = dataFilter.call(this, data, field);
                        if (result === undefined) result = dataFilter.call(this, data.data, field);

                        rule.data = this.data;
                        rule.result = field.old ? result : undefined;
                        me._validatedRule(el, field, result);
                    },
                    function (jqXHR, textStatus) {
                        me._validatedRule(el, field, me.messages[textStatus] || textStatus);
                    }
                ).always(function () {
                    delete me.deferred[key];
                });
            }
            // other result
            else {
                me._validatedRule(el, field, ret);
            }
        },

        // Processing the validation
        _validate: function (el, field) {
            var me = this;

            // doesn't validate the element that has "disabled" or "novalidate" attribute
            if (el.disabled || attr(el, NOVALIDATE) !== null) {
                return;
            }

            field = field || me.getField(el);
            if (!field) return;
            if (!field._rules) me._parse(el);
            if (!field._rules) return;

            me._debug('info', field.key);

            field.isValid = true;
            field.element = el;
            // Cache the value
            field.value = field.getValue();

            // if the field is not required, and that has a blank value
            if (!field.required && !field.must && !field.value) {
                if (!_checkable(el)) {
                    me._validatedField(el, field, {
                        isValid: true
                    });
                    return true;
                }
            }

            me._checkRule(el, field);
            return field.isValid;
        },

        _debug: function (type, messages) {
            if (window.console && this.options.debug) {
                console[type](messages);
            }
        },

        /**
         * Detecting whether the value of an element that matches a rule
         *
         * @method test
         * @param {Element} el - input element
         * @param {String} rule - rule name
         */
        test: function (el, rule) {
            var me = this,
                ret,
                parts = rRule.exec(rule),
                field,
                method,
                params;

            if (parts) {
                method = parts[1];
                if (method in me.rules) {
                    params = parts[2] || parts[3];
                    params = params ? params.split(', ') : undefined;
                    field = me.getField(el, true);
                    field._r = method;
                    field.value = field.getValue();
                    ret = me.rules[method].call(field, el, params);
                }
            }

            return ret === true || ret === undefined || ret === null;
        },

        _getDisplay: function (el, str) {
            return !isString(str) ? isFunction(str) ? str.call(this, el) : '' : str;
        },

        _getMsgOpt: function (obj, field) {
            var opt = field ? field : this.options;
            return $.extend({
                type: 'error',
                pos: _getPos(opt.msgClass),
                target: opt.target,
                wrapper: opt.msgWrapper,
                style: opt.msgStyle,
                cls: opt.msgClass,
                arrow: opt.msgArrow,
                icon: opt.msgIcon
            }, isString(obj) ? {
                msg: obj
            } : obj);
        },

        _getMsgDOM: function (el, msgOpt) {
            var $el = $(el),
                $msgbox, datafor, tgt, container;

            if ($el.is(INPUT_SELECTOR)) {
                tgt = msgOpt.target || attr(el, DATA_TARGET);
                if (tgt) {
                    tgt = !isFunction(tgt) ? tgt.charAt(0) === '#' ? $(tgt) : this.$el.find(tgt) : tgt.call(this, el);
                    if (tgt.length) {
                        if (tgt.is(INPUT_SELECTOR)) {
                            $el = tgt
                            el = tgt.get(0);
                        } else if (tgt.hasClass(CLS_MSG_BOX)) {
                            $msgbox = tgt;
                        } else {
                            container = tgt;
                        }
                    }
                }
                if (!$msgbox) {
                    datafor = (!_checkable(el) || !el.name) && el.id ? el.id : el.name;
                    $msgbox = (container || this.$el).find(msgOpt.wrapper + '.' + CLS_MSG_BOX + '[for="' + datafor + '"]');
                }
            } else {
                $msgbox = $el;
            }

            // Create new message box
            if (!msgOpt.hide && !$msgbox.length) {
                $msgbox = $('<' + msgOpt.wrapper + '>').attr({
                    'class': CLS_MSG_BOX + (msgOpt.cls ? ' ' + msgOpt.cls : ''),
                    'style': msgOpt.style || undefined,
                    'for': datafor
                });

                if (container) {
                    $msgbox.appendTo(container);
                } else {
                    if (_checkable(el)) {
                        var $parent = $el.parent();
                        $msgbox.appendTo($parent.is('label') ? $parent.parent() : $parent);
                    } else {
                        $msgbox[!msgOpt.pos || msgOpt.pos === 'right' ? 'insertAfter' : 'insertBefore']($el);
                    }
                }
            }

            return $msgbox;
        },

        /**
         * Show validation message
         *
         * @method showMsg
         * @param {Element} el - input element
         * @param {Object} msgOpt
         */
        showMsg: function (el, msgOpt, /*INTERNAL*/ field) {
            if (!el) return;
            var me = this,
                opt = me.options,
                msgShow,
                msgMaker,
                temp,
                $msgbox;

            if (isObject(el) && !el.jquery && !msgOpt) {
                $.each(el, function (key, msg) {
                    var el = me.elements[key] || me.$el.find(_key2selector(key))[0];
                    me.showMsg(el, msg);
                });
                return;
            }

            if ($(el).is(INPUT_SELECTOR)) {
                field = field || me.getField(el);
            }

            if (!(msgMaker = (field || opt).msgMaker)) {
                return;
            }

            msgOpt = me._getMsgOpt(msgOpt, field);
            el = (el.name && _checkable(el) ? me.$el.find('input[name="' + el.name + '"]') : $(el)).get(0);

            // ok or tip
            if (!msgOpt.msg && msgOpt.type !== 'error') {
                temp = attr(el, 'data-' + msgOpt.type);
                if (temp !== null) msgOpt.msg = temp;
            }

            if (!isString(msgOpt.msg)) {
                return;
            }

            $msgbox = me._getMsgDOM(el, msgOpt);

            !rPos.test($msgbox[0].className) && $msgbox.addClass(msgOpt.cls);
            if (isIE === 6 && msgOpt.pos === 'bottom') {
                $msgbox[0].style.marginTop = $(el).outerHeight() + 'px';
            }
            $msgbox.html(msgMaker.call(me, msgOpt))[0].style.display = '';

            if (isFunction(msgShow = field && field.msgShow || opt.msgShow)) {
                msgShow.call(me, $msgbox, msgOpt.type);
            }
        },

        /**
         * Hide validation message
         *
         * @method hideMsg
         * @param {Element} el - input element
         * @param {Object} msgOpt optional
         */
        hideMsg: function (el, msgOpt, /*INTERNAL*/ field) {
            var me = this,
                opt = me.options,
                msgHide,
                $msgbox;

            el = $(el).get(0);
            if ($(el).is(INPUT_SELECTOR)) {
                field = field || me.getField(el);
                if (field) {
                    if (field.isValid || me.reseting) attr(el, ARIA_INVALID, null);
                }
            }

            msgOpt = me._getMsgOpt(msgOpt, field);
            msgOpt.hide = true;

            $msgbox = me._getMsgDOM(el, msgOpt);
            if (!$msgbox.length) return;

            if (isFunction(msgHide = field && field.msgHide || opt.msgHide)) {
                msgHide.call(me, $msgbox, msgOpt.type);
            } else {
                $msgbox[0].style.display = 'none';
                $msgbox[0].innerHTML = '';
            }
        },

        /**
         * Get field information
         *
         * @method getField
         * @param {Element} - input element
         * @return {Object} field
         */
        getField: function (el, must) {
            var me = this,
                key,
                field;

            if (isString(el)) {
                key = el;
                el = undefined;
            } else {
                if (attr(el, DATA_RULE)) {
                    return me._parse(el);
                }
                if (el.id && '#' + el.id in me.fields || !el.name) {
                    key = '#' + el.id;
                } else {
                    key = el.name;
                }
            }

            if ((field = me.fields[key]) || must && (field = new me.Field(key))) {
                field.element = el;
            }

            return field;
        },

        /**
         * Config a field
         *
         * @method: setField
         * @param {String} key
         * @param {Object} obj
         */
        setField: function (key, obj) {
            var fields = {};

            if (!key) return;

            // update this field
            if (isString(key)) {
                fields[key] = obj;
            }
            // update fields
            else {
                fields = key;
            }

            this._initFields(fields);
        },

        /**
         * Detecting whether the form is valid
         *
         * @method isFormValid
         * @return {Boolean}
         */
        isFormValid: function () {
            var fields = this.fields,
                k, field;
            for (k in fields) {
                field = fields[k];
                if (!field._rules || !field.required && !field.must && !field.value) continue;
                if (!field.isValid) return false;
            }
            return true;
        },

        /**
         * Prevent submission form
         *
         * @method holdSubmit
         * @param {Boolean} hold - If set to false, will release the hold
         */
        holdSubmit: function (hold) {
            this.submiting = hold === undefined || hold;
        },

        /**
         * Clean validation messages
         *
         * @method cleanUp
         */
        cleanUp: function () {
            this._reset(1);
        },

        /**
         * Destroy the validation
         *
         * @method destroy
         */
        destroy: function () {
            this._reset(1);
            this.$el.off(CLS_NS).removeData(NS);
            attr(this.$el[0], NOVALIDATE, this._NOVALIDATE);
        }
    };

    /**
     * Create Field Factory
     *
     * @class
     * @param  {Object}     context
     * @return {Function}   Factory
     */
    function _createFieldFactory(context) {
        function FieldFactory() {
            var options = this.options;
            for (var i in options) {
                if (i in fieldDefaults) this[i] = options[i];
            }
            $.extend(this, {
                _valHook: function () {
                    return this.element.contentEditable === 'true' ? 'text' : 'val';
                },
                getValue: function () {
                    var elem = this.element;
                    if (elem.type === 'number' && elem.validity && elem.validity.badInput) {
                        return 'NaN';
                    }
                    return $(elem)[this._valHook()]();
                },
                setValue: function (value) {
                    $(this.element)[this._valHook()](this.value = value);
                },
                // Get a range of validation messages
                getRangeMsg: function (value, params, suffix) {
                    if (!params) return;

                    var me = this,
                        msg = me.messages[me._r] || '',
                        result,
                        p = params[0].split('~'),
                        e = params[1] === 'false',
                        a = p[0],
                        b = p[1],
                        c = 'rg',
                        args = [''],
                        isNumber = trim(value) && +value === +value;

                    function compare(large, small) {
                        return !e ? large >= small : large > small;
                    }

                    if (p.length === 2) {
                        if (a && b) {
                            if (isNumber && compare(value, +a) && compare(+b, value)) {
                                result = true;
                            }
                            args = args.concat(p);
                            c = e ? 'gtlt' : 'rg';
                        } else if (a && !b) {
                            if (isNumber && compare(value, +a)) {
                                result = true;
                            }
                            args.push(a);
                            c = e ? 'gt' : 'gte';
                        } else if (!a && b) {
                            if (isNumber && compare(+b, value)) {
                                result = true;
                            }
                            args.push(b);
                            c = e ? 'lt' : 'lte';
                        }
                    } else {
                        if (value === +a) {
                            result = true;
                        }
                        args.push(a);
                        c = 'eq';
                    }

                    if (msg) {
                        if (suffix && msg[c + suffix]) {
                            c += suffix;
                        }
                        args[0] = msg[c];
                    }

                    return result || me._rules && (me._rules[me._i].msg = me.renderMsg.apply(null, args));
                },
                // Render message template
                renderMsg: function () {
                    var args = arguments,
                        tpl = args[0],
                        i = args.length;

                    if (!tpl) return;

                    while (--i) {
                        tpl = tpl.replace('{' + i + '}', args[i]);
                    }

                    return tpl;
                }
            });
        }

        function Field(key, obj, oldField) {
            this.key = key;
            this.validator = context;
            $.extend(this, oldField, obj);
        }

        FieldFactory.prototype = context;
        Field.prototype = new FieldFactory();

        return Field;
    }

    /**
     * Create Rules
     *
     * @class
     * @param {Object} obj     rules
     * @param {Object} context context
     */
    function Rules(obj, context) {
        if (!isObject(obj)) return;

        var k, that = context ? context === true ? this : context : Rules.prototype;

        for (k in obj) {
            if (_checkRuleName(k)) {
                that[k] = _getRule(obj[k]);
            }
        }
    }

    /**
     * Create Messages
     *
     * @class
     * @param {Object} obj     rules
     * @param {Object} context context
     */
    function Messages(obj, context) {
        if (!isObject(obj)) return;

        var k, that = context ? context === true ? this : context : Messages.prototype;

        for (k in obj) {
            that[k] = obj[k];
        }
    }

    // Rule converted factory
    function _getRule(fn) {
        switch ($.type(fn)) {
            case 'function':
                return fn;
            case 'array':
                var f = function () {
                    return fn[0].test(this.value) || fn[1] || false;
                };
                f.msg = fn[1];
                return f;
            case 'regexp':
                return function () {
                    return fn.test(this.value);
                };
        }
    }

    // Get instance by an element
    function _getInstance(el) {
        var wrap, k, options;

        if (!el || !el.tagName) return;

        switch (el.tagName) {
            case 'INPUT':
            case 'SELECT':
            case 'TEXTAREA':
            case 'BUTTON':
            case 'FIELDSET':
                wrap = el.form || $(el).closest('.' + CLS_WRAPPER);
                break;
            case 'FORM':
                wrap = el;
                break;
            default:
                wrap = $(el).closest('.' + CLS_WRAPPER);
        }

        for (k in preinitialized) {
            if ($(wrap).is(k)) {
                options = preinitialized[k];
                break;
            }
        }

        return $(wrap).data(NS) || $(wrap)[NS](options).data(NS);
    }

    // Get custom rules on the node
    function _getDataRule(el, method) {
        var fn = trim(attr(el, DATA_RULE + '-' + method));

        if (fn && (fn = new Function('return ' + fn)())) {
            return _getRule(fn);
        }
    }

    // Get custom messages on the node
    function _getDataMsg(el, field, m) {
        var msg = field.msg,
            item = field._r;

        if (isObject(msg)) msg = msg[item];
        if (!isString(msg)) {
            msg = attr(el, DATA_MSG + '-' + item) || attr(el, DATA_MSG) || (m ? isString(m) ? m : m[item] : '');
        }

        return msg;
    }

    // Get message position
    function _getPos(str) {
        var pos;

        if (str) pos = rPos.exec(str);
        return pos && pos[0];
    }

    // Check whether the element is checkbox or radio
    function _checkable(el) {
        return el.tagName === 'INPUT' && el.type === 'checkbox' || el.type === 'radio';
    }

    // Parse date string to timestamp
    function _parseDate(str) {
        return Date.parse(str.replace(/\.|\-/g, '/'));
    }

    // Rule name only allows alphanumeric characters and underscores
    function _checkRuleName(name) {
        return /^\w+$/.test(name);
    }

    // Translate field key to jQuery selector.
    function _key2selector(key) {
        var isID = key.charAt(0) === '#';
        key = key.replace(/([:.{(|)}/\[\]])/g, '\\$1');
        return isID ? key : '[name="' + key + '"]:first';
    }


    // Fixed a issue cause by refresh page in IE.
    $(window).on('beforeunload', function () {
        this.focus();
    });

    $(document)
        .on('click', ':submit', function () {
            var input = this,
                attrNode;
            if (!input.form) return;
            // Shim for "formnovalidate"
            attrNode = input.getAttributeNode('formnovalidate');
            if (attrNode && attrNode.nodeValue !== null || attr(input, NOVALIDATE) !== null) {
                novalidateonce = true;
            }
        })
        // Automatic initializing form validation
        .on('focusin submit validate', 'form,.' + CLS_WRAPPER, function (e) {
            if (attr(this, NOVALIDATE) !== null) return;
            var $form = $(this),
                me;

            if (!$form.data(NS) && (me = _getInstance(this))) {
                if (!$.isEmptyObject(me.fields)) {
                    // Execute event handler
                    if (e.type === 'focusin') {
                        me._focusin(e);
                    } else {
                        me._submit(e);
                    }
                } else {
                    attr(this, NOVALIDATE, NOVALIDATE);
                    $form.off(CLS_NS).removeData(NS);
                }
            }
        });

    new Messages({
        fallback: 'This field is not valid.',
        loading: 'Validating...'
    });


    // Built-in rules (global)
    new Rules({

        /**
         * required
         *
         * @example:
            required
            required(jqSelector)
            required(anotherRule)
            required(not, -1)
            required(from, .contact)
         */
        required: function (element, params) {
            var me = this,
                val = trim(me.value),
                isValid = true;

            if (params) {
                if (params.length === 1) {
                    if (!_checkRuleName(params[0])) {
                        if (!val && !$(params[0], me.$el).length) {
                            return null;
                        }
                    } else if (me.rules[params[0]]) {
                        if (!val && !me.test(element, params[0])) {
                            return null;
                        }
                    }
                } else if (params[0] === 'not') {
                    $.each(params.slice(1), function () {
                        return (isValid = val !== trim(this));
                    });
                } else if (params[0] === 'from') {
                    var $elements = me.$el.find(params[1]),
                        VALIDATED = '_validated_',
                        ret;

                    isValid = $elements.filter(function () {
                        var field = me.getField(this);
                        return field && !!trim(field.getValue());
                    }).length >= (params[2] || 1);

                    if (isValid) {
                        if (!val) ret = null;
                    } else {
                        ret = _getDataMsg($elements[0], me) || false;
                    }

                    if (!$(element).data(VALIDATED)) {
                        $elements.data(VALIDATED, 1).each(function () {
                            if (element !== this) {
                                me._validate(this);
                            }
                        }).removeData(VALIDATED);
                    }

                    return ret;
                }
            }

            return isValid && !!val;
        },

        /**
         * integer
         *
         * @example:
            integer
            integer[+]
            integer[+0]
            integer[-]
            integer[-0]
         */
        integer: function (element, params) {
            var re, z = '0|',
                p = '[1-9]\\d*',
                key = params ? params[0] : '*';

            switch (key) {
                case '+':
                    re = p;
                    break;
                case '-':
                    re = '-' + p;
                    break;
                case '+0':
                    re = z + p;
                    break;
                case '-0':
                    re = z + '-' + p;
                    break;
                default:
                    re = z + '-?' + p;
            }
            re = '^(?:' + re + ')$';

            return new RegExp(re).test(this.value) || (this.messages.integer && this.messages.integer[key]);
        },

        /**
         * match another field
         *
         * @example:
            match[password]    Match the password field (two values ​​must be the same)
            match[eq, password]  Ditto
            match[neq, count]  The value must be not equal to the value of the count field
            match[lt, count]   The value must be less than the value of the count field
            match[lte, count]  The value must be less than or equal to the value of the count field
            match[gt, count]   The value must be greater than the value of the count field
            match[gte, count]  The value must be greater than or equal to the value of the count field
            match[gte, startDate, date]
            match[gte, startTime, time]
         **/
        match: function (element, params) {
            if (!params) return;

            var me = this,
                isValid = true,
                a, b,
                key, msg, type = 'eq',
                parser,
                selector2, elem2, field2;

            if (params.length === 1) {
                key = params[0];
            } else {
                type = params[0];
                key = params[1];
            }

            selector2 = _key2selector(key);
            elem2 = me.$el.find(selector2)[0];
            // If the compared field is not exist
            if (!elem2) return;
            field2 = me.getField(elem2);
            a = me.value;
            b = field2.getValue();

            if (!me._match) {
                me.$el.on('valid' + CLS_NS_FIELD + CLS_NS, selector2, function () {
                    $(element).trigger('validate');
                });
                me._match = field2._match = 1;
            }

            // If both fields are blank
            if (!me.required && a === '' && b === '') {
                return null;
            }

            parser = params[2];
            if (parser) {
                if (/^date(time)?$/i.test(parser)) {
                    a = _parseDate(a);
                    b = _parseDate(b);
                } else if (parser === 'time') {
                    a = +a.replace(/:/g, '');
                    b = +b.replace(/:/g, '');
                }
            }

            // If the compared field is incorrect, we only ensure that this field is correct.
            if (type !== 'eq' && !isNaN(+a) && isNaN(+b)) {
                return true;
            }

            switch (type) {
                case 'lt':
                    isValid = +a < +b;
                    break;
                case 'lte':
                    isValid = +a <= +b;
                    break;
                case 'gte':
                    isValid = +a >= +b;
                    break;
                case 'gt':
                    isValid = +a > +b;
                    break;
                case 'neq':
                    isValid = a !== b;
                    break;
                default:
                    isValid = a === b;
            }

            return isValid || (
                isObject(me.messages.match) &&
                me.messages.match[type].replace('{1}', me._getDisplay(elem2, field2.display || key))
            );
        },

        /**
         * range numbers
         *
         * @example:
            range[0~99]    Number 0-99
            range[0~]      Number greater than or equal to 0
            range[~100]    Number less than or equal to 100
         **/
        range: function (element, params) {
            return this.getRangeMsg(this.value, params);
        },

        /**
         * how many checkbox or radio inputs that checked
         *
         * @example:
            checked;       no empty, same to required
            checked[1~3]   1-3 items
            checked[1~]    greater than 1 item
            checked[~3]    less than 3 items
            checked[3]     3 items
         **/
        checked: function (element, params) {
            if (!_checkable(element)) return;

            var me = this,
                elem, count;

            if (element.name) {
                count = me.$el.find('input[name="' + element.name + '"]').filter(function () {
                    var el = this;
                    if (!elem && _checkable(el)) elem = el;
                    return !el.disabled && el.checked;
                }).length;
            } else {
                elem = element;
                count = elem.checked;
            }

            if (params) {
                return me.getRangeMsg(count, params);
            } else {
                return !!count || _getDataMsg(elem, me, '') || me.messages.required || false;
            }
        },

        /**
         * length of a characters (You can pass the second parameter "true", will calculate the length in bytes)
         *
         * @example:
            length[6~16]        6-16 characters
            length[6~]          Greater than 6 characters
            length[~16]         Less than 16 characters
            length[~16, true]   Less than 16 characters, non-ASCII characters calculating two-character
         **/
        length: function (element, params) {
            var value = this.value,
                len = (params[1] === 'true' ? value.replace(rDoubleBytes, 'xx') : value).length;

            return this.getRangeMsg(len, params, (params[1] ? '_2' : ''));
        },

        /**
         * remote validation
         *
         * @description
         *  remote([get:]url [, name1, [name2 ...]]);
         *  Adaptation three kinds of results (Front for the successful, followed by a failure):
                1. text:
                    ''  'Error Message'
                2. json:
                    {"ok": ""}  {"error": "Error Message"}
                3. json wrapper:
                    {"status": 1, "data": {"ok": ""}}  {"status": 1, "data": {"error": "Error Message"}}
         * @example
            The simplest:       remote(path/to/server);
            With parameters:    remote(path/to/server, name1, name2, ...);
            By GET:             remote(get:path/to/server, name1, name2, ...);
            Name proxy:         remote(path/to/server, name1, proxyname2:name2, proxyname3:#id3, ...)
            Query String        remote(path/to/server, foo=1&bar=2, name1, name2, ...)
            CORS                remote(cors:path/to/server)
            JSONP               remote(jsonp:path/to/server)
         */
        remote: function (element, params) {
            if (!params) return;

            var me = this,
                arr = rAjaxType.exec(params[0]),
                rule = me._rules[me._i],
                data = {},
                queryString = '',
                url = arr[3],
                type = arr[2] || 'POST', // GET / POST
                rType = (arr[1] || '').toLowerCase(), // CORS / JSONP
                dataType;

            rule.must = true;
            data[element.name] = me.value;

            // There are extra fields
            if (params[1]) {
                $.map(params.slice(1), function (name) {
                    var arr, key;
                    if (~name.indexOf('=')) {
                        queryString += '&' + name;
                    } else {
                        arr = name.split(':');
                        name = trim(arr[0]);
                        key = trim(arr[1]) || name;
                        data[name] = me.$el.find(_key2selector(key)).val();
                    }
                });
            }

            data = $.param(data) + queryString;
            if (!me.must && rule.data && rule.data === data) {
                return rule.result;
            }

            // Cross-domain request, force jsonp dataType
            if (rType !== 'cors' && /^https?:/.test(url) && !~url.indexOf(location.host)) {
                dataType = 'jsonp';
            }

            // Asynchronous validation need return jqXHR objects
            return $.ajax({
                url: url,
                type: type,
                data: data,
                dataType: dataType
            });
        },

        /**
         * filter characters, direct filtration without prompting error (support custom regular expressions)
         *
         * @example
         *  filter          filtering unsafe characters
         *  filter(regexp)  filtering the "regexp" matched characters
         */
        filter: function (element, params) {
            var value = this.value,
                temp = value.replace(params ? (new RegExp('[' + params[0] + ']', 'gm')) : rUnsafe, '');
            if (temp !== value) this.setValue(temp);
        }
    });


    /**
     * Config global options
     *
     * @static  config
     * @param {Object} options
     */
    Validator.config = function (key, value) {
        if (isObject(key)) {
            $.each(key, _config);
        } else if (isString(key)) {
            _config(key, value);
        }

        function _config(k, o) {
            if (k === 'rules') {
                new Rules(o);
            } else if (k === 'messages') {
                new Messages(o);
            } else if (k in fieldDefaults) {
                fieldDefaults[k] = o;
            } else {
                defaults[k] = o;
            }
        }
    };

    /**
     * Config themes
     *
     * @static setTheme
     * @param {String|Object} name
     * @param {Object} obj
     * @example
        .setTheme( themeName, themeOptions )
        .setTheme( multiThemes )
     */
    Validator.setTheme = function (name, obj) {
        if (isObject(name)) {
            $.extend(true, themes, name);
        } else if (isString(name) && isObject(obj)) {
            themes[name] = $.extend(themes[name], obj);
        }
    };

    /**
     * Resource loader
     *
     * @static load
     * @param {String} str
     * @example
        .load('local=zh-CN')        // load: local/zh-CN.js and jquery.validator.css
        .load('local=zh-CN&css=')   // load: local/zh-CN.js
        .load('local&css')          // load: local/en.js (set <html lang="en">) and jquery.validator.css
        .load('local')              // dito
     */
    Validator.load = function (str) {
        if (!str) return;
        var doc = document,
            params = {},
            node = doc.scripts[0],
            dir, el, ONLOAD;

        str.replace(/([^?=&]+)=([^&#]*)/g, function (m, key, value) {
            params[key] = value;
        });

        dir = params.dir || Validator.dir;

        if (!Validator.css && params.css !== '') {
            el = doc.createElement('link');
            el.rel = 'stylesheet';
            el.href = Validator.css = dir + 'jquery.validator.css';
            node.parentNode.insertBefore(el, node);
        }
        if (!Validator.local && ~str.indexOf('local') && params.local !== '') {
            Validator.local = (params.local || doc.documentElement.lang || 'en').replace('_', '-');
            Validator.pending = 1;
            el = doc.createElement('script');
            el.src = dir + 'local/' + Validator.local + '.js';
            ONLOAD = 'onload' in el ? 'onload' : 'onreadystatechange';
            el[ONLOAD] = function () {
                if (!el.readyState || /loaded|complete/.test(el.readyState)) {
                    el = el[ONLOAD] = null;
                    delete Validator.pending;
                    $(window).triggerHandler('validatorready');
                }
            };
            node.parentNode.insertBefore(el, node);
        }
    };

    // Auto loading resources
    (function () {
        var scripts = document.scripts,
            i = scripts.length,
            node, arr,
            re = /(.*validator(?:\.min)?.js)(\?.*(?:local|css|dir)(?:=[\w\-]*)?)?/;

        while (i-- && !arr) {
            node = scripts[i];
            arr = (node.hasAttribute ? node.src : node.getAttribute('src', 4) || '').match(re);
        }

        if (!arr) return;
        Validator.dir = arr[1].split('/').slice(0, -1).join('/') + '/';
        Validator.load(arr[2]);
    })();

    return $[NS] = Validator;
}));

/*********************************
 * Themes, rules, and i18n support
 * Locale: Chinese; 中文
 *********************************/
(function (factory) {
    typeof module === "object" && module.exports ? module.exports = factory(require("jquery")) :
        typeof define === 'function' && define.amd ? define('validator-lang', ['jquery'], factory) :
        factory(jQuery);
}(function ($) {

    /* Global configuration
     */
    $.validator.config({
        //stopOnError: true,
        //focusCleanup: true,
        //theme: 'yellow_right',
        //timely: 2,

        // Custom rules
        rules: {
            digits: [/^\d+$/, "请填写数字"],
            letters: [/^[a-z]+$/i, "请填写字母"],
            date: [/^\d{4}-\d{2}-\d{2}$/, "请填写有效的日期，格式:yyyy-mm-dd"],
            time: [/^([01]\d|2[0-3])(:[0-5]\d){1,2}$/, "请填写有效的时间，00:00到23:59之间"],
            email: [/^[\w\+\-]+(\.[\w\+\-]+)*@[a-z\d\-]+(\.[a-z\d\-]+)*\.([a-z]{2,4})$/i, "请填写有效的邮箱"],
            url: [/^(https?|s?ftp):\/\/\S+$/i, "请填写有效的网址"],
            qq: [/^[1-9]\d{4,}$/, "请填写有效的QQ号"],
            IDcard: [/^\d{6}(19|2\d)?\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)?$/, "请填写正确的身份证号码"],
            tel: [/^(?:(?:0\d{2,3}[\- ]?[1-9]\d{6,7})|(?:[48]00[\- ]?[1-9]\d{6}))$/, "请填写有效的电话号码"],
            mobile: [/^1[3-9]\d{9}$/, "请填写有效的手机号"],
            zipcode: [/^\d{6}$/, "请检查邮政编码格式"],
            chinese: [/^[\u0391-\uFFE5]+$/, "请填写中文字符"],
            username: [/^\w{3,12}$/, "请填写3-12位数字、字母、下划线"],
            password: [/^[\S]{6,16}$/, "请填写6-16位字符，不能包含空格"],
            accept: function (element, params) {
                if (!params) return true;
                var ext = params[0],
                    value = $(element).val();
                return (ext === '*') ||
                    (new RegExp(".(?:" + ext + ")$", "i")).test(value) ||
                    this.renderMsg("只接受{1}后缀的文件", ext.replace(/\|/g, ','));
            }

        },

        // Default error messages
        messages: {
            0: "此处",
            fallback: "{0}格式不正确",
            loading: "正在验证...",
            error: "网络异常",
            timeout: "请求超时",
            required: "{0}不能为空",
            remote: "{0}已被使用",
            integer: {
                '*': "请填写整数",
                '+': "请填写正整数",
                '+0': "请填写正整数或0",
                '-': "请填写负整数",
                '-0': "请填写负整数或0"
            },
            match: {
                eq: "{0}与{1}不一致",
                neq: "{0}与{1}不能相同",
                lt: "{0}必须小于{1}",
                gt: "{0}必须大于{1}",
                lte: "{0}不能大于{1}",
                gte: "{0}不能小于{1}"
            },
            range: {
                rg: "请填写{1}到{2}的数",
                gte: "请填写不小于{1}的数",
                lte: "请填写最大{1}的数",
                gtlt: "请填写{1}到{2}之间的数",
                gt: "请填写大于{1}的数",
                lt: "请填写小于{1}的数"
            },
            checked: {
                eq: "请选择{1}项",
                rg: "请选择{1}到{2}项",
                gte: "请至少选择{1}项",
                lte: "请最多选择{1}项"
            },
            length: {
                eq: "请填写{1}个字符",
                rg: "请填写{1}到{2}个字符",
                gte: "请至少填写{1}个字符",
                lte: "请最多填写{1}个字符",
                eq_2: "",
                rg_2: "",
                gte_2: "",
                lte_2: ""
            }
        }
    });

    /* Themes
     */
    var TPL_ARROW = '<span class="n-arrow"><b>◆</b><i>◆</i></span>';
    $.validator.setTheme({
        'simple_right': {
            formClass: 'n-simple',
            msgClass: 'n-right'
        },
        'simple_bottom': {
            formClass: 'n-simple',
            msgClass: 'n-bottom'
        },
        'yellow_top': {
            formClass: 'n-yellow',
            msgClass: 'n-top',
            msgArrow: TPL_ARROW
        },
        'yellow_right': {
            formClass: 'n-yellow',
            msgClass: 'n-right',
            msgArrow: TPL_ARROW
        },
        'yellow_right_effect': {
            formClass: 'n-yellow',
            msgClass: 'n-right',
            msgArrow: TPL_ARROW,
            msgShow: function ($msgbox, type) {
                var $el = $msgbox.children();
                if ($el.is(':animated')) return;
                if (type === 'error') {
                    $el.css({
                            left: '20px',
                            opacity: 0
                        })
                        .delay(100).show().stop()
                        .animate({
                            left: '-4px',
                            opacity: 1
                        }, 150)
                        .animate({
                            left: '3px'
                        }, 80)
                        .animate({
                            left: 0
                        }, 80);
                } else {
                    $el.css({
                        left: 0,
                        opacity: 1
                    }).fadeIn(200);
                }
            },
            msgHide: function ($msgbox, type) {
                var $el = $msgbox.children();
                $el.stop().delay(100).show()
                    .animate({
                        left: '20px',
                        opacity: 0
                    }, 300, function () {
                        $msgbox.hide();
                    });
            }
        }
    });
}));

define('validator', ['validator-core', 'validator-lang'], function (Validator, undefined) {
    return Validator;
});

/**
 * FastAdmin通用搜索
 *
 * @author: pppscn <35696959@qq.com>
 * @update 2017-05-07 <https://gitee.com/pp/fastadmin>
 *
 * @author: Karson <karsonzhang@163.com>
 * @update 2018-04-05 <https://gitee.com/karson/fastadmin>
 */

! function ($) {
    'use strict';

    var ColumnsForSearch = [];

    var sprintf = $.fn.bootstrapTable.utils.sprintf;

    var initCommonSearch = function (pColumns, that) {
        var vFormCommon = createFormCommon(pColumns, that);

        var vModal = sprintf("<div class=\"commonsearch-table %s\">", that.options.searchFormVisible ? "" : "hidden");
        vModal += vFormCommon;
        vModal += "</div>";
        that.$container.prepend($(vModal));
        that.$commonsearch = $(".commonsearch-table", that.$container);
        var form = $("form.form-commonsearch", that.$commonsearch);

        require(['form'], function (Form) {
            Form.api.bindevent(form);
            form.validator("destroy");
        });

        // 表单提交
        form.on("submit", function (event) {
            event.preventDefault();
            that.onCommonSearch();
            return false;
        });

        // 重置搜索
        form.on("click", "button[type=reset]", function (event) {
            form[0].reset();
            that.onCommonSearch();
        });

    };

    var createFormCommon = function (pColumns, that) {
        // 如果有使用模板则直接返回模板的内容
        if (that.options.searchFormTemplate) {
            return Template(that.options.searchFormTemplate, {
                columns: pColumns,
                table: that
            });
        }
        var htmlForm = [];
        htmlForm.push(sprintf('<form class="form-horizontal form-commonsearch" novalidate method="post" action="%s" >', that.options.actionForm));
        htmlForm.push('<fieldset>');
        if (that.options.titleForm.length > 0)
            htmlForm.push(sprintf("<legend>%s</legend>", that.options.titleForm));
        htmlForm.push('<div class="row">');
        for (var i in pColumns) {
            var vObjCol = pColumns[i];
            if (!vObjCol.checkbox && vObjCol.field !== 'operate' && vObjCol.searchable && vObjCol.operate !== false) {
                var query = Fast.api.query(vObjCol.field);
                var operate = Fast.api.query(vObjCol.field + "-operate");

                vObjCol.defaultValue = that.options.renderDefault && query ? query : (typeof vObjCol.defaultValue === 'undefined' ? '' : vObjCol.defaultValue);
                vObjCol.operate = that.options.renderDefault && operate ? operate : (typeof vObjCol.operate === 'undefined' ? '=' : vObjCol.operate);
                ColumnsForSearch.push(vObjCol);
                vObjCol.searchClass = typeof vObjCol.searchClass === 'undefined' ? '' : vObjCol.searchClass;

                htmlForm.push('<div class="form-group col-xs-12 col-sm-6 col-md-4 col-lg-3 ' + vObjCol.searchClass + '">');
                htmlForm.push(sprintf('<label for="%s" class="control-label col-xs-4">%s</label>', vObjCol.field, vObjCol.title));
                htmlForm.push('<div class="col-xs-8">');

                vObjCol.operate = vObjCol.operate ? vObjCol.operate.toUpperCase() : '=';
                htmlForm.push(sprintf('<input type="hidden" class="form-control operate" name="%s-operate" data-name="%s" value="%s" readonly>', vObjCol.field, vObjCol.field, vObjCol.operate));

                var addClass = typeof vObjCol.addClass === 'undefined' ? (typeof vObjCol.addclass === 'undefined' ? 'form-control' : 'form-control ' + vObjCol.addclass) : 'form-control ' + vObjCol.addClass;
                var extend = typeof vObjCol.extend === 'undefined' ? '' : vObjCol.extend;
                var style = typeof vObjCol.style === 'undefined' ? '' : sprintf('style="%s"', vObjCol.style);
                extend = typeof vObjCol.data !== 'undefined' && extend == '' ? vObjCol.data : extend;
                if (vObjCol.searchList) {
                    if (typeof vObjCol.searchList === 'function') {
                        htmlForm.push(vObjCol.searchList.call(this, vObjCol));
                    } else {
                        var optionList = [sprintf('<option value="">%s</option>', that.options.formatCommonChoose())];
                        if (typeof vObjCol.searchList === 'object' && typeof vObjCol.searchList.then === 'function') {
                            (function (vObjCol, that) {
                                $.when(vObjCol.searchList).done(function (ret) {
                                    var searchList = [];
                                    if (ret.data && ret.data.searchlist && $.isArray(ret.data.searchlist)) {
                                        searchList = ret.data.searchlist;
                                    } else if (ret.constructor === Array || ret.constructor === Object) {
                                        searchList = ret;
                                    }
                                    var optionList = createOptionList(searchList, vObjCol, that);
                                    $("form.form-commonsearch select[name='" + vObjCol.field + "']", that.$container).html(optionList.join(''));
                                });
                            })(vObjCol, that);
                        } else {
                            optionList = createOptionList(vObjCol.searchList, vObjCol, that);
                        }
                        htmlForm.push(sprintf('<select class="%s" name="%s" %s %s>%s</select>', addClass, vObjCol.field, style, extend, optionList.join('')));
                    }
                } else {
                    var placeholder = typeof vObjCol.placeholder === 'undefined' ? vObjCol.title : vObjCol.placeholder;
                    var type = typeof vObjCol.type === 'undefined' ? 'text' : vObjCol.type;
                    var defaultValue = typeof vObjCol.defaultValue === 'undefined' ? '' : vObjCol.defaultValue;
                    if (/BETWEEN$/.test(vObjCol.operate)) {
                        var defaultValueArr = defaultValue.toString().match(/\|/) ? defaultValue.split('|') : ['', ''];
                        var placeholderArr = placeholder.toString().match(/\|/) ? placeholder.split('|') : [placeholder, placeholder];
                        htmlForm.push('<div class="row row-between">');
                        htmlForm.push(sprintf('<div class="col-xs-6"><input type="%s" class="%s" name="%s" value="%s" placeholder="%s" id="%s" data-index="%s" %s %s></div>', type, addClass, vObjCol.field, defaultValueArr[0], placeholderArr[0], vObjCol.field, i, style, extend));
                        htmlForm.push(sprintf('<div class="col-xs-6"><input type="%s" class="%s" name="%s" value="%s" placeholder="%s" id="%s" data-index="%s" %s %s></div>', type, addClass, vObjCol.field, defaultValueArr[1], placeholderArr[1], vObjCol.field, i, style, extend));
                        htmlForm.push('</div>');
                    } else {
                        htmlForm.push(sprintf('<input type="%s" class="%s" name="%s" value="%s" placeholder="%s" id="%s" data-index="%s" %s %s>', type, addClass, vObjCol.field, defaultValue, placeholder, vObjCol.field, i, style, extend));
                    }
                }

                htmlForm.push('</div>');
                htmlForm.push('</div>');
            }
        }
        htmlForm.push('<div class="form-group col-xs-12 col-sm-6 col-md-4 col-lg-3">');
        htmlForm.push(createFormBtn(that).join(''));
        htmlForm.push('</div>');
        htmlForm.push('</div>');
        htmlForm.push('</fieldset>');
        htmlForm.push('</form>');

        return htmlForm.join('');
    };

    var createFormBtn = function (that) {
        var htmlBtn = [];
        var searchSubmit = that.options.formatCommonSubmitButton();
        var searchReset = that.options.formatCommonResetButton();
        htmlBtn.push('<div class="col-sm-8 col-xs-offset-4">');
        htmlBtn.push(sprintf('<button type="submit" class="btn btn-success" formnovalidate>%s</button> ', searchSubmit));
        htmlBtn.push(sprintf('<button type="reset" class="btn btn-default" >%s</button> ', searchReset));
        htmlBtn.push('</div>');
        return htmlBtn;
    };

    var createOptionList = function (searchList, vObjCol, that) {
        var isArray = searchList.constructor === Array;
        var optionList = [];
        optionList.push(sprintf('<option value="">%s</option>', that.options.formatCommonChoose()));
        $.each(searchList, function (key, value) {
            if (value.constructor === Object) {
                key = value.id;
                value = value.name;
            } else {
                key = isArray ? value : key;
            }
            optionList.push(sprintf("<option value='" + key + "' %s>" + value + "</option>", key == vObjCol.defaultValue ? 'selected' : ''));
        });
        return optionList;
    };

    var isSearchAvailble = function (that) {

        //只支持服务端搜索
        if (!that.options.commonSearch || that.options.sidePagination != 'server' || !that.options.url) {
            return false;
        }

        return true;
    };

    var getSearchQuery = function (that, removeempty) {
        var op = {};
        var filter = {};
        var value = '';
        $("form.form-commonsearch .operate", that.$commonsearch).each(function (i) {
            var name = $(this).data("name");
            var sym = $(this).is("select") ? $("option:selected", this).val() : $(this).val().toUpperCase();
            var obj = $("[name='" + name + "']", that.$commonsearch);
            if (obj.size() == 0)
                return true;
            var vObjCol = ColumnsForSearch[i];
            if (obj.size() > 1) {
                if (/BETWEEN$/.test(sym)) {
                    var value_begin = $.trim($("[name='" + name + "']:first", that.$commonsearch).val()),
                        value_end = $.trim($("[name='" + name + "']:last", that.$commonsearch).val());
                    if (value_begin.length || value_end.length) {
                        if (typeof vObjCol.process === 'function') {
                            value_begin = vObjCol.process(value_begin, 'begin');
                            value_end = vObjCol.process(value_end, 'end');
                        }
                        value = value_begin + ',' + value_end;
                    } else {
                        value = '';
                    }
                    //如果是时间筛选，将operate置为RANGE
                    if ($("[name='" + name + "']:first", that.$commonsearch).hasClass("datetimepicker")) {
                        sym = 'RANGE';
                    }
                } else {
                    value = $("[name='" + name + "']:checked", that.$commonsearch).val();
                    value = (vObjCol && typeof vObjCol.process === 'function') ? vObjCol.process(value) : value;
                }
            } else {
                value = (vObjCol && typeof vObjCol.process === 'function') ? vObjCol.process(obj.val()) : obj.val();
            }
            if (removeempty && (value == '' || value == null || ($.isArray(value) && value.length == 0)) && !sym.match(/null/i)) {
                return true;
            }

            op[name] = sym;
            filter[name] = value;
        });
        return {
            op: op,
            filter: filter
        };
    };

    var getQueryParams = function (params, searchQuery, removeempty) {
        params.filter = typeof params.filter === 'Object' ? params.filter : (params.filter ? JSON.parse(params.filter) : {});
        params.op = typeof params.op === 'Object' ? params.op : (params.op ? JSON.parse(params.op) : {});

        params.filter = $.extend({}, params.filter, searchQuery.filter);
        params.op = $.extend({}, params.op, searchQuery.op);
        //移除empty的值
        if (removeempty) {
            $.each(params.filter, function (i, j) {
                if ((j == '' || j == null || ($.isArray(j) && j.length == 0)) && !params.op[i].match(/null/i)) {
                    delete params.filter[i];
                    delete params.op[i];
                }
            });
        }
        params.filter = JSON.stringify(params.filter);
        params.op = JSON.stringify(params.op);
        return params;
    };

    $.extend($.fn.bootstrapTable.defaults, {
        commonSearch: false,
        titleForm: "Common search",
        actionForm: "",
        searchFormTemplate: "",
        searchFormVisible: true,
        searchClass: 'searchit',
        showSearch: true,
        renderDefault: true,
        onCommonSearch: function (field, text) {
            return false;
        },
        onPostCommonSearch: function (table) {
            return false;
        }
    });

    $.extend($.fn.bootstrapTable.defaults.icons, {
        commonSearchIcon: 'glyphicon-search'
    });

    $.extend($.fn.bootstrapTable.Constructor.EVENTS, {
        'common-search.bs.table': 'onCommonSearch',
        'post-common-search.bs.table': 'onPostCommonSearch'
    });
    $.extend($.fn.bootstrapTable.locales[$.fn.bootstrapTable.defaults.locale], {
        formatCommonSearch: function () {
            return "Common search";
        },
        formatCommonSubmitButton: function () {
            return "Submit";
        },
        formatCommonResetButton: function () {
            return "Reset";
        },
        formatCommonCloseButton: function () {
            return "Close";
        },
        formatCommonChoose: function () {
            return "Choose";
        }
    });

    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales);

    var BootstrapTable = $.fn.bootstrapTable.Constructor,
        _initHeader = BootstrapTable.prototype.initHeader,
        _initToolbar = BootstrapTable.prototype.initToolbar,
        _load = BootstrapTable.prototype.load,
        _initSearch = BootstrapTable.prototype.initSearch;

    BootstrapTable.prototype.initHeader = function () {
        _initHeader.apply(this, Array.prototype.slice.apply(arguments));
        this.$header.find('th[data-field]').each(function (i) {
            var column = $(this).data();
            if (typeof column['width'] !== 'undefined') {
                $(this).css("min-width", column['width']);
            }
        });
    };
    BootstrapTable.prototype.initToolbar = function () {
        _initToolbar.apply(this, Array.prototype.slice.apply(arguments));

        if (!isSearchAvailble(this)) {
            return;
        }

        var that = this,
            html = [];
        if (that.options.showSearch) {
            html.push(sprintf('<div class="columns-%s pull-%s" style="margin-top:10px;margin-bottom:10px;">', this.options.buttonsAlign, this.options.buttonsAlign));
            html.push(sprintf('<button class="btn btn-default%s' + '" type="button" name="commonSearch" title="%s">', that.options.iconSize === undefined ? '' : ' btn-' + that.options.iconSize, that.options.formatCommonSearch()));
            html.push(sprintf('<i class="%s %s"></i>', that.options.iconsPrefix, that.options.icons.commonSearchIcon))
            html.push('</button></div>');
        }
        if (that.$toolbar.find(".pull-right").size() > 0) {
            $(html.join('')).insertBefore(that.$toolbar.find(".pull-right:first"));
        } else {
            that.$toolbar.append(html.join(''));
        }

        initCommonSearch(that.columns, that);

        that.$toolbar.find('button[name="commonSearch"]')
            .off('click').on('click', function () {
                that.$commonsearch.toggleClass("hidden");
                return;
            });

        that.$container.on("click", "." + that.options.searchClass, function () {
            var obj = $("form [name='" + $(this).data("field") + "']", that.$commonsearch);
            if (obj.size() > 0) {
                var value = $(this).data("value");
                if (obj.is("select")) {
                    $("option[value='" + value + "']", obj).prop("selected", true);
                } else if (obj.size() > 1) {
                    $("form [name='" + $(this).data("field") + "'][value='" + value + "']", that.$commonsearch).prop("checked", true);
                } else {
                    obj.val(value);
                }
                obj.trigger("change");
                $("form", that.$commonsearch).trigger("submit");
            }
        });
        var queryParams = that.options.queryParams;
        //匹配默认搜索值
        this.options.queryParams = function (params) {
            return queryParams(getQueryParams(params, getSearchQuery(that, true)));
        };
        this.trigger('post-common-search', that);

    };

    BootstrapTable.prototype.onCommonSearch = function () {
        var searchQuery = getSearchQuery(this);
        this.trigger('common-search', this, searchQuery);
        this.options.pageNumber = 1;
        this.refresh({});
    };

    BootstrapTable.prototype.load = function (data) {
        _load.apply(this, Array.prototype.slice.apply(arguments));

        if (!isSearchAvailble(this)) {
            return;
        }
    };

    BootstrapTable.prototype.initSearch = function () {
        _initSearch.apply(this, Array.prototype.slice.apply(arguments));

        if (!isSearchAvailble(this)) {
            return;
        }

        var that = this;
        var fp = $.isEmptyObject(this.filterColumnsPartial) ? null : this.filterColumnsPartial;
        this.data = fp ? $.grep(this.data, function (item, i) {
            for (var key in fp) {
                var fval = fp[key].toLowerCase();
                var value = item[key];
                value = $.fn.bootstrapTable.utils.calculateObjectValue(that.header,
                    that.header.formatters[$.inArray(key, that.header.fields)],
                    [value, item, i], value);

                if (!($.inArray(key, that.header.fields) !== -1 &&
                        (typeof value === 'string' || typeof value === 'number') &&
                        (value + '').toLowerCase().indexOf(fval) !== -1)) {
                    return false;
                }
            }
            return true;
        }) : this.data;
    };
}(jQuery);

define("bootstrap-table-commonsearch", ["bootstrap-table"], (function (global) {
    return function () {
        var ret, fn;
        return ret || global.$.fn.bootstrapTable.defaults;
    };
}(this)));

/**
 * 将BootstrapTable的行使用自定义的模板来渲染
 * 
 * @author: karson
 * @version: v0.0.1
 *
 * @update 2017-06-24 <http://github.com/karsonzhang/fastadmin>
 */

! function ($) {
    'use strict';

    $.extend($.fn.bootstrapTable.defaults, {
        //是否启用模板渲染
        templateView: false,
        //数据格式化的模板ID或格式函数
        templateFormatter: "itemtpl",
        //添加的父类的class
        templateParentClass: "row row-flex",
        //向table添加的class
        templateTableClass: "table-template",

    });

    var BootstrapTable = $.fn.bootstrapTable.Constructor,
        _initContainer = BootstrapTable.prototype.initContainer,
        _initBody = BootstrapTable.prototype.initBody,
        _initRow = BootstrapTable.prototype.initRow;

    BootstrapTable.prototype.initContainer = function () {
        _initContainer.apply(this, Array.prototype.slice.apply(arguments));
        var that = this;
        if (!that.options.templateView) {
            return;
        }
        that.options.cardView = true;

    };

    BootstrapTable.prototype.initBody = function () {
        var that = this;
        $.extend(that.options, {
            showHeader: !that.options.templateView ? $.fn.bootstrapTable.defaults.showHeader : false,
            showFooter: !that.options.templateView ? $.fn.bootstrapTable.defaults.showFooter : false,
        });
        $(that.$el).toggleClass(that.options.templateTableClass, that.options.templateView);

        _initBody.apply(this, Array.prototype.slice.apply(arguments));

        if (!that.options.templateView) {
            return;
        } else {
            //由于Bootstrap是基于Table的，添加一个父类容器
            $("> *:not(.no-records-found)", that.$body).wrapAll($("<div />").addClass(that.options.templateParentClass));
        }
    };

    BootstrapTable.prototype.initRow = function (item, i, data, parentDom) {
        var that = this;
        //如果未启用则使用原生的initRow方法
        if (!that.options.templateView) {
            return _initRow.apply(that, Array.prototype.slice.apply(arguments));
        }
        var $content = '';
        if (typeof that.options.templateFormatter === 'function') {
            $content = that.options.templateFormatter.call(that, item, i, data);
        } else {
            var Template = require('template');
            $content = Template(that.options.templateFormatter, {
                item: item,
                i: i,
                data: data
            });
        }
        return $content;
    };

}(jQuery);

define("bootstrap-table-template", ["bootstrap-table", "template"], (function (global) {
    return function () {
        var ret, fn;
        return ret || global.$.fn.bootstrapTable.defaults;
    };
}(this)));

/*!
 * jQuery Cookie Plugin v1.4.1
 * https://github.com/carhartl/jquery-cookie
 *
 * Copyright 2013 Klaus Hartl
 * Released under the MIT license
 */
(function (factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD
        define('cookie', ['jquery'], factory);
    } else if (typeof exports === 'object') {
        // CommonJS
        factory(require('jquery'));
    } else {
        // Browser globals
        factory(jQuery);
    }
}(function ($) {

    var pluses = /\+/g;

    function encode(s) {
        return config.raw ? s : encodeURIComponent(s);
    }

    function decode(s) {
        return config.raw ? s : decodeURIComponent(s);
    }

    function stringifyCookieValue(value) {
        return encode(config.json ? JSON.stringify(value) : String(value));
    }

    function parseCookieValue(s) {
        if (s.indexOf('"') === 0) {
            // This is a quoted cookie as according to RFC2068, unescape...
            s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
        }

        try {
            // Replace server-side written pluses with spaces.
            // If we can't decode the cookie, ignore it, it's unusable.
            // If we can't parse the cookie, ignore it, it's unusable.
            s = decodeURIComponent(s.replace(pluses, ' '));
            return config.json ? JSON.parse(s) : s;
        } catch (e) {}
    }

    function read(s, converter) {
        var value = config.raw ? s : parseCookieValue(s);
        return $.isFunction(converter) ? converter(value) : value;
    }

    var config = $.cookie = function (key, value, options) {

        // Write

        if (value !== undefined && !$.isFunction(value)) {
            options = $.extend({}, config.defaults, options);

            if (typeof options.expires === 'number') {
                var days = options.expires,
                    t = options.expires = new Date();
                t.setTime(+t + days * 864e+5);
            }

            return (document.cookie = [
                encode(key), '=', stringifyCookieValue(value),
                options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
                options.path ? '; path=' + options.path : '',
                options.domain ? '; domain=' + options.domain : '',
                options.secure ? '; secure' : ''
            ].join(''));
        }

        // Read

        var result = key ? undefined : {};

        // To prevent the for loop in the first place assign an empty array
        // in case there are no cookies at all. Also prevents odd result when
        // calling $.cookie().
        var cookies = document.cookie ? document.cookie.split('; ') : [];

        for (var i = 0, l = cookies.length; i < l; i++) {
            var parts = cookies[i].split('=');
            var name = decode(parts.shift());
            var cookie = parts.join('=');

            if (key && key === name) {
                // If second argument (value) is a function it's a converter...
                result = read(cookie, value);
                break;
            }

            // Prevent storing a cookie that we couldn't decode.
            if (!key && (cookie = read(cookie)) !== undefined) {
                result[name] = cookie;
            }
        }

        return result;
    };

    config.defaults = {};

    $.removeCookie = function (key, options) {
        if ($.cookie(key) === undefined) {
            return false;
        }

        // Must not alter options, thus extending a fresh object...
        $.cookie(key, '', $.extend({}, options, {
            expires: -1
        }));
        return !$.cookie(key);
    };

}));

/*!
 * @author: lihaitao
 * @webSite: http://blog.csdn.net/lhtzbj12/
 * @version: v1.0.0
 * @opensource:https://gitee.com/lhtzbj12/bootstrap-table-maintainColSwitch.js
 * @description: 扩展Bootstrap-table插件，通过showColumns显示隐藏列时将设置保存到cookie或者数据库,下次打开时仍保持
 */
(function ($) {
    $.extend($.fn.bootstrapTable.defaults, {
        maintainColSwitch: false,
    });
    var BootstrapTable = $.fn.bootstrapTable.Constructor,
        _initTable = BootstrapTable.prototype.initTable;
    BootstrapTable.prototype.initTable = function () {
        var that = this;
        _initTable.apply(this, Array.prototype.slice.apply(arguments));
        var Default = {
            initShowColumns: [],
            cookieKey: window.location.pathname.replace(/\/|\./g, "_") + "_colSwitch_" + that.$el.prop("id"),
            cookieExpires: 7,
            onSave: function (columns) {
                return false
            },
            onLoad: function () {
                return false
            }
        };
        if (that.options.showColumns && that.options.maintainColSwitch) {
            that.options.maintainColSwitch = $.extend(Default, that.options.maintainColSwitch)
        } else {
            return
        }
        var showCols = [];
        if (that.options.maintainColSwitch.initShowColumns.length > 0) {
            showCols = that.options.maintainColSwitch.initShowColumns
        } else {
            var columns = $.cookie(that.options.maintainColSwitch.cookieKey);
            if (columns) {
                showCols = columns.split("|")
            }
        }
        if (showCols.length > 0) {
            $(that.options.columns[0]).each(function (i, e) {
                if (e.field === "state") {
                    return true
                }
                if (e.field === 0) {
                    return true
                }
                var inShow = $(showCols).filter(function (i1, e1) {
                    return e1 === e.field
                });
                e.visible = inShow.length > 0
            });
            if (that.options.maintainColSwitch.onLoad) {
                that.options.maintainColSwitch.onLoad()
            }
        }
        that.$el.on("column-switch.bs.table", function (e, field, checked) {
            var opts = $(this).bootstrapTable("getOptions");
            var columns = $(opts.columns[0]).map(function (i, e) {
                return e.visible === true && e.field !== "state" ? e.field : null
            }).get();
            $.cookie(opts.maintainColSwitch.cookieKey, columns.join("|"), {
                expires: opts.maintainColSwitch.cookieExpires
            });
            if (opts.maintainColSwitch.onSave) {
                opts.maintainColSwitch.onSave(columns)
            }
        });
        that.$el.on("load-success.bs.table", function (e) {
            var $keepOpen = that.$toolbar.find(".keep-open");
            if (showCols.length > 0 && showCols.length <= that.options.minimumCountColumns) {
                $keepOpen.find("input:checked").prop("disabled", true)
            }
        })
    }
})(jQuery);
define("bootstrap-table-maintain", ["bootstrap-table", "cookie"], (function (global) {
    return function () {
        var ret, fn;
        return ret || global.$.fn.bootstrapTable.defaults;
    };
}(this)));

define('table', ['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table', 'bootstrap-table-lang', 'bootstrap-table-export', 'bootstrap-table-commonsearch', 'bootstrap-table-template', 'bootstrap-table-maintain'], function ($, undefined, Moment) {
    var Table = {
        list: {},
        // Bootstrap-table 基础配置
        defaults: {
            url: '',
            sidePagination: 'server',
            method: 'get', //请求方法
            toolbar: ".toolbar", //工具栏
            search: true, //是否启用快速搜索
            cache: false,
            commonSearch: true, //是否启用通用搜索
            searchFormVisible: false, //是否始终显示搜索表单
            titleForm: '', //为空则不显示标题，不定义默认显示：普通搜索
            idTable: 'commonTable',
            showExport: true,
            exportDataType: "all",
            exportTypes: ['json', 'xml', 'csv', 'txt', 'doc', 'excel'],
            pageSize: 10,
            pageList: [10, 25, 50, 'All'],
            pagination: true,
            clickToSelect: true, //是否启用点击选中
            dblClickToEdit: true, //是否启用双击编辑
            singleSelect: false, //是否启用单选
            showRefresh: false,
            locale: 'zh-CN',
            showToggle: true,
            showColumns: true,
            pk: 'id',
            sortName: 'id',
            sortOrder: 'desc',
            paginationFirstText: __("First"),
            paginationPreText: __("Previous"),
            paginationNextText: __("Next"),
            paginationLastText: __("Last"),
            cardView: false, //卡片视图
            checkOnInit: true, //是否在初始化时判断
            maintainColSwitch: {
                cookieExpires: 3650, //自定义过期时间
            },
            escape: true, //是否对内容进行转义
            extend: {
                index_url: '',
                add_url: '',
                edit_url: '',
                del_url: '',
                import_url: '',
                multi_url: '',
                dragsort_url: 'ajax/weigh',
            }
        },
        // Bootstrap-table 列配置
        columnDefaults: {
            align: 'center',
            valign: 'middle',
        },
        config: {
            firsttd: 'tbody tr td:first-child:not(:has(div.card-views))',
            toolbar: '.toolbar',
            refreshbtn: '.btn-refresh',
            addbtn: '.btn-add',
            editbtn: '.btn-edit',
            delbtn: '.btn-del',
            importbtn: '.btn-import',
            multibtn: '.btn-multi',
            disabledbtn: '.btn-disabled',
            editonebtn: '.btn-editone',
            dragsortfield: 'weigh',
        },
        button: {
            edit: {
                name: 'edit',
                icon: 'fa fa-pencil',
                title: __('Edit'),
                extend: 'data-toggle="tooltip"',
                classname: 'btn btn-xs btn-success btn-editone'
            },
            del: {
                name: 'del',
                icon: 'fa fa-trash',
                title: __('Del'),
                extend: 'data-toggle="tooltip"',
                classname: 'btn btn-xs btn-danger btn-delone'
            },
            dragsort: {
                name: 'dragsort',
                icon: 'fa fa-arrows',
                title: __('Drag to sort'),
                extend: 'data-toggle="tooltip"',
                classname: 'btn btn-xs btn-primary btn-dragsort'
            }
        },
        api: {
            init: function (defaults, columnDefaults, locales) {
                defaults = defaults ? defaults : {};
                columnDefaults = columnDefaults ? columnDefaults : {};
                locales = locales ? locales : {};
                // 如果是iOS设备则启用卡片视图
                if (navigator.userAgent.match(/(iPod|iPhone|iPad)/)) {
                    Table.defaults.cardView = true;
                }
                // 写入bootstrap-table默认配置
                $.extend(true, $.fn.bootstrapTable.defaults, Table.defaults, defaults);
                // 写入bootstrap-table column配置
                $.extend($.fn.bootstrapTable.columnDefaults, Table.columnDefaults, columnDefaults);
                // 写入bootstrap-table locale配置
                $.extend($.fn.bootstrapTable.locales[Table.defaults.locale], {
                    formatCommonSearch: function () {
                        return __('Common search');
                    },
                    formatCommonSubmitButton: function () {
                        return __('Submit');
                    },
                    formatCommonResetButton: function () {
                        return __('Reset');
                    },
                    formatCommonCloseButton: function () {
                        return __('Close');
                    },
                    formatCommonChoose: function () {
                        return __('Choose');
                    }
                }, locales);
            },
            // 绑定事件
            bindevent: function (table) {
                //Bootstrap-table的父元素,包含table,toolbar,pagnation
                var parenttable = table.closest('.bootstrap-table');
                //Bootstrap-table配置
                var options = table.bootstrapTable('getOptions');
                //Bootstrap操作区
                var toolbar = $(options.toolbar, parenttable);
                table.on('load-success.bs.table', function (e, data) {
                    // 当前搜索条件高亮
                    $(".form-commonsearch select option:selected").each(function () {
                        if (this.value) {
                            $(this).parent().addClass("formCheckd")
                            $(this).parent().parent().prev('label').addClass("formCheckd-label")
                        } else {
                            $(this).parent().removeClass("formCheckd")
                            $(this).parent().parent().prev('label').removeClass("formCheckd-label")
                        }
                    });
                    $(".form-commonsearch input[type='text']").each(function () {
                        if (this.value) {
                            $(this).addClass("formCheckd")
                            $(this).parent().prev('label').addClass("formCheckd-label")
                        } else {
                            $(this).removeClass("formCheckd")
                            $(this).parent().prev('label').removeClass("formCheckd-label")
                        }
                    });
                });
                //当刷新表格时
                table.on('load-error.bs.table', function (status, res, e) {
                    if (e.status === 0) {
                        return;
                    }
                    Toastr.error(__('Unknown data format'));
                });
                //当刷新表格时
                table.on('refresh.bs.table', function (e, settings, data) {
                    $(Table.config.refreshbtn, toolbar).find(".fa").addClass("fa-spin");
                });
                if (options.dblClickToEdit) {
                    //当双击单元格时
                    table.on('dbl-click-row.bs.table', function (e, row, element, field) {
                        $(Table.config.editonebtn, element).trigger("click");
                    });
                }
                //当内容渲染完成后
                table.on('post-body.bs.table', function (e, settings, json, xhr) {
                    $(Table.config.refreshbtn, toolbar).find(".fa").removeClass("fa-spin");
                    $(Table.config.disabledbtn, toolbar).toggleClass('disabled', true);
                    if ($(Table.config.firsttd, table).find("input[type='checkbox'][data-index]").size() > 0) {
                        // 挺拽选择,需要重新绑定事件
                        require(['drag', 'drop'], function () {
                            $(Table.config.firsttd, table).drag("start", function (ev, dd) {
                                return $('<div class="selection" />').css('opacity', .65).appendTo(document.body);
                            }).drag(function (ev, dd) {
                                $(dd.proxy).css({
                                    top: Math.min(ev.pageY, dd.startY),
                                    left: Math.min(ev.pageX, dd.startX),
                                    height: Math.abs(ev.pageY - dd.startY),
                                    width: Math.abs(ev.pageX - dd.startX)
                                });
                            }).drag("end", function (ev, dd) {
                                $(dd.proxy).remove();
                            });
                            $(Table.config.firsttd, table).drop("start", function () {
                                Table.api.toggleattr(this);
                            }).drop(function () {
                                Table.api.toggleattr(this);
                            }).drop("end", function () {
                                Table.api.toggleattr(this);
                            });
                            $.drop({
                                multi: true
                            });
                        });
                    }
                });
                // 处理选中筛选框后按钮的状态统一变更
                table.on('check.bs.table uncheck.bs.table check-all.bs.table uncheck-all.bs.table', function () {
                    var ids = Table.api.selectedids(table);
                    $(Table.config.disabledbtn, toolbar).toggleClass('disabled', !ids.length);
                });
                // 绑定TAB事件
                $('.panel-heading ul[data-field] li a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
                    var field = $(this).closest("ul").data("field");
                    var type = $(this).closest("ul").data("type");
                    var value = $(this).data("value");
                    if (type == 'select' || !type) {
                        $("select[name='" + field + "'] option[value='" + value + "']", table.closest(".bootstrap-table").find(".commonsearch-table")).prop("selected", true);
                    } else {
                        var format = 'YYYY-MM-DD HH:mm:ss';
                        if (value == 'today') {
                            value = Moment().startOf('day').format(format) + " - " + Moment().endOf('day').format(format);
                        } else if (value == 'yesterday') {
                            value = Moment().subtract(1, 'days').startOf('day').format(format) + " - " + Moment().subtract(1, 'days').endOf('day').format(format);
                        } else if (value == 'thismonth') {
                            value = Moment().startOf('month').format(format) + " - " + Moment().endOf('month').format(format);
                        } else if (value == 'lastmonth') {
                            value = Moment().subtract(1, 'month').startOf('month').format(format) + " - " + Moment().subtract(1, 'month').endOf('month').format(format);
                        } else if (value == 'last2month') {
                            value = Moment().subtract(2, 'month').startOf('month').format(format) + " - " + Moment().subtract(2, 'month').endOf('month').format(format);
                        } else if (value == 'last3month') {
                            value = Moment().subtract(3, 'month').startOf('month').format(format) + " - " + Moment().subtract(3, 'month').endOf('month').format(format);
                        }
                        $("#" + field + "").val(value);
                    }
                    table.bootstrapTable('refresh', {});
                    return false;
                });

                $('.toolbar select[data-field]').change(function () {
                    var field = $(this).closest("select").data("field");
                    $("[name='" + field + "']").val($(this).val());
                    table.bootstrapTable('refresh', {});
                    return false;
                })


                // 刷新按钮事件
                $(toolbar).on('click', Table.config.refreshbtn, function () {
                    table.bootstrapTable('refresh');
                });
                // 添加按钮事件
                $(toolbar).on('click', Table.config.addbtn, function () {
                    var ids = Table.api.selectedids(table);
                    var url = options.extend.add_url;
                    if (url.indexOf("{ids}") !== -1) {
                        url = Table.api.replaceurl(url, {
                            ids: ids.length > 0 ? ids.join(",") : 0
                        }, table);
                    }
                    Fast.api.open(url, __('Add'), $(this).data() || {});
                });
                // 导入按钮事件
                if ($(Table.config.importbtn, toolbar).size() > 0) {
                    require(['upload'], function (Upload) {
                        Upload.api.plupload($(Table.config.importbtn, toolbar), function (data, ret) {
                            Fast.api.ajax({
                                url: options.extend.import_url,
                                data: {
                                    file: data.url
                                },
                            }, function (data, ret) {
                                table.bootstrapTable('refresh');
                            });
                        });
                    });
                }
                // 批量编辑按钮事件
                $(toolbar).on('click', Table.config.editbtn, function () {
                    var that = this;
                    //循环弹出多个编辑框
                    $.each(table.bootstrapTable('getSelections'), function (index, row) {
                        var url = options.extend.edit_url;
                        row = $.extend({}, row ? row : {}, {
                            ids: row[options.pk]
                        });
                        var url = Table.api.replaceurl(url, row, table);
                        Fast.api.open(url, __('Edit'), $(that).data() || {});
                    });
                });
                // 批量操作按钮事件
                $(toolbar).on('click', Table.config.multibtn, function () {
                    var ids = Table.api.selectedids(table);
                    Table.api.multi($(this).data("action"), ids, table, this);
                });
                // 批量删除按钮事件
                $(toolbar).on('click', Table.config.delbtn, function () {
                    var that = this;
                    var ids = Table.api.selectedids(table);
                    Layer.confirm(
                        __('Are you sure you want to delete the %s selected item?', ids.length), {
                            icon: 3,
                            title: __('Warning'),
                            offset: 0,
                            shadeClose: true
                        },
                        function (index) {
                            Table.api.multi("del", ids, table, that);
                            Layer.close(index);
                        }
                    );
                });
                // 拖拽排序
                require(['dragsort'], function () {
                    //绑定拖动排序
                    $("tbody", table).dragsort({
                        itemSelector: 'tr:visible',
                        dragSelector: "a.btn-dragsort",
                        dragEnd: function (a, b) {
                            var element = $("a.btn-dragsort", this);
                            var data = table.bootstrapTable('getData');
                            var current = data[parseInt($(this).data("index"))];
                            var options = table.bootstrapTable('getOptions');
                            //改变的值和改变的ID集合
                            var ids = $.map($("tbody tr:visible", table), function (tr) {
                                return data[parseInt($(tr).data("index"))][options.pk];
                            });
                            var changeid = current[options.pk];
                            var pid = typeof current.pid != 'undefined' ? current.pid : '';
                            var params = {
                                url: table.bootstrapTable('getOptions').extend.dragsort_url,
                                data: {
                                    ids: ids.join(','),
                                    changeid: changeid,
                                    pid: pid,
                                    field: Table.config.dragsortfield,
                                    orderway: options.sortOrder,
                                    table: options.extend.table
                                }
                            };
                            Fast.api.ajax(params, function (data, ret) {
                                var success = $(element).data("success") || $.noop;
                                if (typeof success === 'function') {
                                    if (false === success.call(element, data, ret)) {
                                        return false;
                                    }
                                }
                                table.bootstrapTable('refresh');
                            }, function () {
                                var error = $(element).data("error") || $.noop;
                                if (typeof error === 'function') {
                                    if (false === error.call(element, data, ret)) {
                                        return false;
                                    }
                                }
                                table.bootstrapTable('refresh');
                            });
                        },
                        placeHolderTemplate: ""
                    });
                });
                $(table).on("click", "input[data-id][name='checkbox']", function (e) {
                    var ids = $(this).data("id");
                    var row = Table.api.getrowbyid(table, ids);
                    table.trigger('check.bs.table', [row, this]);
                });
                $(table).on("click", "[data-id].btn-change", function (e) {
                    e.preventDefault();
                    Table.api.multi($(this).data("action") ? $(this).data("action") : '', [$(this).data("id")], table, this);
                });
                $(table).on("click", "[data-id].btn-edit", function (e) {
                    e.preventDefault();
                    var ids = $(this).data("id");
                    var row = Table.api.getrowbyid(table, ids);
                    row.ids = ids;
                    var url = Table.api.replaceurl(options.extend.edit_url, row, table);
                    Fast.api.open(url, __('Edit'), $(this).data() || {});
                });
                $(table).on("click", "[data-id].btn-del", function (e) {
                    e.preventDefault();
                    var id = $(this).data("id");
                    var that = this;
                    Layer.confirm(
                        __('Are you sure you want to delete this item?'), {
                            icon: 3,
                            title: __('Warning'),
                            shadeClose: true
                        },
                        function (index) {
                            Table.api.multi("del", id, table, that);
                            Layer.close(index);
                        }
                    );
                });
                // 隐藏某一些选择列
                $('.commonsearch-table .column_hide').each(function () {
                    let field = $(this).attr('id')
                    if (!field) {
                        field = $(this).attr('name')
                    }
                    $('.fixed-table-toolbar .columns input[data-field="' + field + '"]').parents('li').hide();
                })
                var id = table.attr("id");
                Table.list[id] = table;
                return table;
            },
            // 批量操作请求
            multi: function (action, ids, table, element) {
                var options = table.bootstrapTable('getOptions');
                var data = element ? $(element).data() : {};
                var ids = ($.isArray(ids) ? ids.join(",") : ids);
                var url = typeof data.url !== "undefined" ? data.url : (action == "del" ? options.extend.del_url : options.extend.multi_url);
                url = this.replaceurl(url, {
                    ids: ids
                }, table);
                var params = typeof data.params !== "undefined" ? (typeof data.params == 'object' ? $.param(data.params) : data.params) : '';
                var options = {
                    url: url,
                    data: {
                        action: action,
                        ids: ids,
                        params: params
                    }
                };
                Fast.api.ajax(options, function (data, ret) {
                    var success = $(element).data("success") || $.noop;
                    if (typeof success === 'function') {
                        if (false === success.call(element, data, ret)) {
                            return false;
                        }
                    }
                    table.bootstrapTable('refresh');
                }, function (data, ret) {
                    var error = $(element).data("error") || $.noop;
                    if (typeof error === 'function') {
                        if (false === error.call(element, data, ret)) {
                            return false;
                        }
                    }
                });
            },
            // 单元格元素事件
            events: {
                operate: {
                    'click .btn-editone': function (e, value, row, index) {
                        e.stopPropagation();
                        e.preventDefault();
                        var table = $(this).closest('table');
                        var options = table.bootstrapTable('getOptions');
                        var ids = row[options.pk];
                        row = $.extend({}, row ? row : {}, {
                            ids: ids
                        });
                        var url = options.extend.edit_url;
                        Fast.api.open(Table.api.replaceurl(url, row, table), __('Edit'), $(this).data() || {});
                    },
                    'click .btn-delone': function (e, value, row, index) {
                        e.stopPropagation();
                        e.preventDefault();
                        var that = this;
                        var top = $(that).offset().top - $(window).scrollTop();
                        var left = $(that).offset().left - $(window).scrollLeft() - 260;
                        if (top + 154 > $(window).height()) {
                            top = top - 154;
                        }
                        if ($(window).width() < 480) {
                            top = left = undefined;
                        }
                        Layer.confirm(
                            __('Are you sure you want to delete this item?'), {
                                icon: 3,
                                title: __('Warning'),
                                offset: [top, left],
                                shadeClose: true
                            },
                            function (index) {
                                var table = $(that).closest('table');
                                var options = table.bootstrapTable('getOptions');
                                Table.api.multi("del", row[options.pk], table, that);
                                Layer.close(index);
                            }
                        );
                    }
                }
            },
            // 单元格数据格式化
            formatter: {
                icon: function (value, row, index) {
                    if (!value)
                        return '';
                    value = value.indexOf(" ") > -1 ? value : "fa fa-" + value;
                    //渲染fontawesome图标
                    return '<i class="' + value + '"></i> ' + value;
                },
                image: function (value, row, index) {
                    value = value ? value : '/assets/img/blank.gif';
                    var classname = typeof this.classname !== 'undefined' ? this.classname : 'img-sm img-center';
                    return '<a href="' + Fast.api.cdnurl(value) + '" target="_blank"><img class="' + classname + '" src="' + Fast.api.cdnurl(value) + '" /></a>';
                },
                images: function (value, row, index) {
                    value = value === null ? '' : value.toString();
                    var classname = typeof this.classname !== 'undefined' ? this.classname : 'img-sm img-center';
                    var arr = value.split(',');
                    var html = [];
                    $.each(arr, function (i, value) {
                        value = value ? value : '/assets/img/blank.gif';
                        html.push('<a href="' + Fast.api.cdnurl(value) + '" target="_blank"><img class="' + classname + '" src="' + Fast.api.cdnurl(value) + '" /></a>');
                    });
                    return html.join(' ');
                },
                content: function (value, row, index) {
                    var width = this.width != undefined ? this.width : 250;
                    return "<div style='white-space: nowrap; text-overflow:ellipsis; overflow: hidden; max-width:" + width + "px;'>" + value + "</div>";
                },
                status: function (value, row, index) {
                    //颜色状态数组,可使用red/yellow/aqua/blue/navy/teal/olive/lime/fuchsia/purple/maroon
                    var colorArr = {
                        normal: 'success',
                        hidden: 'grey',
                        deleted: 'danger',
                        locked: 'info'
                    };
                    //如果字段列有定义custom
                    if (typeof this.custom !== 'undefined') {
                        colorArr = $.extend(colorArr, this.custom);
                    }
                    value = value === null ? '' : value.toString();
                    var color = value && typeof colorArr[value] !== 'undefined' ? colorArr[value] : 'primary';
                    var newValue = value.charAt(0).toUpperCase() + value.slice(1);
                    //渲染状态
                    var html = '<span class="text-' + color + '"><i class="fa fa-circle"></i> ' + __(newValue) + '</span>';
                    if (this.operate != false) {
                        html = '<a href="javascript:;" class="searchit" data-toggle="tooltip" title="' + __('Click to search %s', __(newValue)) + '" data-field="' + this.field + '" data-value="' + value + '">' + html + '</a>';
                    }
                    return html;
                },
                //和最新版的status效果一致
                custom_status: function (value, row, index) {
                    var custom = {
                        normal: 'success',
                        hidden: 'gray',
                        deleted: 'danger',
                        locked: 'info'
                    };
                    if (typeof this.custom !== 'undefined') {
                        custom = $.extend(custom, this.custom);
                    }
                    this.custom = custom;
                    this.icon = 'fa fa-circle';
                    return Table.api.formatter.normal.call(this, value, row, index);
                },
                //会带上彩色
                normal: function (value, row, index) {
                    var colorArr = ["primary", "success", "danger", "warning", "info", "gray", "red", "yellow", "aqua", "blue", "navy", "teal", "olive", "lime", "fuchsia", "purple", "maroon"];
                    var custom = {};
                    if (typeof this.custom !== 'undefined') {
                        custom = $.extend(custom, this.custom);
                    }
                    value = value === null ? '' : value.toString();
                    var keys = typeof this.searchList === 'object' ? Object.keys(this.searchList) : [];
                    var index = keys.indexOf(value);
                    var color = value && typeof custom[value] !== 'undefined' ? custom[value] : null;
                    var display = index > -1 ? this.searchList[value] : null;
                    var icon = typeof this.icon !== 'undefined' ? this.icon : null;
                    if (!color) {
                        color = index > -1 && typeof colorArr[index] !== 'undefined' ? colorArr[index] : 'primary';
                    }
                    if (!display) {
                        display = __(value.charAt(0).toUpperCase() + value.slice(1));
                    }
                    var html = '<span class="text-' + color + '">' + (icon ? '<i class="' + icon + '"></i> ' : '') + display + '</span>';
                    if (this.operate != false) {
                        html = '<a href="javascript:;" class="searchit" data-toggle="tooltip" title="' + __('Click to search %s', display) + '" data-field="' + this.field + '" data-value="' + value + '">' + html + '</a>';
                    }
                    return html;
                },
                toggle: function (value, row, index) {
                    var color = typeof this.color !== 'undefined' ? this.color : 'success';
                    var yes = typeof this.yes !== 'undefined' ? this.yes : 1;
                    var no = typeof this.no !== 'undefined' ? this.no : 0;
                    return "<a href='javascript:;' data-toggle='tooltip' title='" + __('Click to toggle') + "' class='btn-change' data-id='" +
                        row.id + "' data-params='" + this.field + "=" + (value == yes ? no : yes) + "'><i class='fa fa-toggle-on " + (value == yes ? 'text-' + color : 'fa-flip-horizontal text-gray') + " fa-2x'></i></a>";
                },
                url: function (value, row, index) {
                    return '<div class="input-group input-group-sm" style="width:250px;margin:0 auto;"><input type="text" class="form-control input-sm" value="' + value + '"><span class="input-group-btn input-group-sm"><a href="' + value + '" target="_blank" class="btn btn-default btn-sm"><i class="fa fa-link"></i></a></span></div>';
                },
                search: function (value, row, index) {
                    return '<a href="javascript:;" class="searchit" data-toggle="tooltip" title="' + __('Click to search %s', value) + '" data-field="' + this.field + '" data-value="' + value + '">' + value + '</a>';
                },
                addtabs: function (value, row, index) {
                    var url = Table.api.replaceurl(this.url, row, this.table);
                    var title = this.atitle ? this.atitle : __("Search %s", value);
                    return '<a href="' + Fast.api.fixurl(url) + '" class="addtabsit" data-value="' + value + '" title="' + title + '">' + value + '</a>';
                },
                dialog: function (value, row, index) {
                    var url = Table.api.replaceurl(this.url, row, this.table);
                    var title = this.atitle ? this.atitle : __("View %s", value);
                    return '<a href="' + Fast.api.fixurl(url) + '" class="dialogit" data-value="' + value + '" title="' + title + '">' + value + '</a>';
                },
                flag: function (value, row, index) {
                    value = value === null ? '' : value.toString();
                    var colorArr = {
                        index: 'success',
                        hot: 'warning',
                        recommend: 'danger',
                        'new': 'info'
                    };
                    //如果字段列有定义custom
                    if (typeof this.custom !== 'undefined') {
                        colorArr = $.extend(colorArr, this.custom);
                    }
                    if (typeof this.customField !== 'undefined' && typeof row[this.customField] !== 'undefined') {
                        value = row[this.customField];
                    }
                    //渲染Flag
                    var html = [];
                    var arr = value.split(',');
                    $.each(arr, function (i, value) {
                        value = value === null ? '' : value.toString();
                        if (value == '')
                            return true;
                        var color = value && typeof colorArr[value] !== 'undefined' ? colorArr[value] : 'primary';
                        value = value.charAt(0).toUpperCase() + value.slice(1);
                        html.push('<span class="label label-' + color + '">' + __(value) + '</span>');
                    });
                    return html.join(' ');
                },
                label: function (value, row, index) {
                    return Table.api.formatter.flag.call(this, value, row, index);
                },
                datetime: function (value, row, index) {
                    var datetimeFormat = typeof this.datetimeFormat === 'undefined' ? 'YYYY-MM-DD HH:mm:ss' : this.datetimeFormat;
                    if (isNaN(value)) {
                        return value ? Moment(value).format(datetimeFormat) : __('None');
                    } else {
                        return value ? Moment(parseInt(value) * 1000).format(datetimeFormat) : __('None');
                    }
                },
                dataYear: function (value, row, index) {
                    var dateyearFormat = typeof this.datetimeFormat === 'undefined' ? 'YYYY-MM-DD' : this.datetimeFormat;
                    if (isNaN(value)) {
                        return value ? Moment(value).format(dateyearFormat) : __('None');
                    } else {
                        return value ? Moment(parseInt(value) * 1000).format(dateyearFormat) : __('None');
                    }
                },
                operate: function (value, row, index) {
                    var table = this.table;
                    // 操作配置
                    var options = table ? table.bootstrapTable('getOptions') : {};
                    // 默认按钮组
                    var buttons = $.extend([], this.buttons || []);

                    if (options.extend.dragsort_url !== '') {
                        buttons.push({
                            name: 'dragsort',
                            icon: 'fa fa-arrows',
                            title: __('Drag to sort'),
                            extend: 'data-toggle="tooltip"',
                            classname: 'btn btn-xs btn-primary btn-dragsort'
                        });
                    }
                    if (options.extend.edit_url !== '') {
                        buttons.push({
                            name: 'edit',
                            icon: 'fa fa-pencil',
                            title: __('Edit'),
                            extend: 'data-toggle="tooltip"',
                            classname: 'btn btn-xs btn-success btn-editone',
                            url: options.extend.edit_url
                        });
                    }
                    if (options.extend.del_url !== '') {
                        buttons.push({
                            name: 'del',
                            icon: 'fa fa-trash',
                            title: __('Del'),
                            extend: 'data-toggle="tooltip"',
                            classname: 'btn btn-xs btn-danger btn-delone'
                        });
                    }
                    return Table.api.buttonlink(this, buttons, value, row, index, 'operate');
                },
                buttons: function (value, row, index) {
                    // 默认按钮组
                    var buttons = $.extend([], this.buttons || []);
                    return Table.api.buttonlink(this, buttons, value, row, index, 'buttons');
                },
                singleButtons: function (value, row, index) {
                    // 单行按钮组
                    var buttons = $.extend([], this.buttons || []);
                    return Table.api.singleButtonlink(this, buttons, value, row, index, 'buttons');
                }
            },
            buttonlink: function (column, buttons, value, row, index, type) {
                var table = column.table;
                type = typeof type === 'undefined' ? 'buttons' : type;
                var options = table ? table.bootstrapTable('getOptions') : {};
                var html = [];
                var hidden, visible, url, classname, icon, text, title, refresh, confirm, extend;
                var fieldIndex = column.fieldIndex;

                $.each(buttons, function (i, j) {
                    if (type === 'operate') {
                        if (j.name === 'dragsort' && typeof row[Table.config.dragsortfield] === 'undefined') {
                            return true;
                        }
                        if (['add', 'edit', 'del', 'multi', 'dragsort'].indexOf(j.name) > -1 && !options.extend[j.name + "_url"]) {
                            return true;
                        }
                    }
                    var attr = table.data(type + "-" + j.name);
                    if (typeof attr === 'undefined' || attr) {
                        hidden = typeof j.hidden === 'function' ? j.hidden.call(table, row, j) : (j.hidden ? j.hidden : false);
                        if (hidden) {
                            return true;
                        }
                        visible = typeof j.visible === 'function' ? j.visible.call(table, row, j) : (j.visible ? j.visible : true);
                        if (!visible) {
                            return true;
                        }
                        url = j.url ? j.url : '';
                        url = typeof url === 'function' ? url.call(table, row, j) : (url ? Fast.api.fixurl(Table.api.replaceurl(url, row, table)) : 'javascript:;');
                        classname = j.classname ? j.classname : 'btn-primary btn-' + name + 'one';
                        icon = j.icon ? j.icon : '';
                        text = j.text ? j.text : '';
                        title = j.title ? j.title : text;
                        refresh = j.refresh ? 'data-refresh="' + j.refresh + '"' : '';
                        confirm = j.confirm ? 'data-confirm="' + j.confirm + '"' : '';
                        extend = j.extend ? j.extend : '';
                        html.push('<a href="' + url + '" class="' + classname + '" ' + (confirm ? confirm + ' ' : '') + (refresh ? refresh + ' ' : '') + extend + ' title="' + title + '" data-table-id="' + (table ? table.attr("id") : '') + '" data-field-index="' + fieldIndex + '" data-row-index="' + index + '" data-button-index="' + i + '"><i class="' + icon + '"></i>' + (text ? ' ' + text : '') + '</a>');
                    }
                });
                return html.join(' ');
            },
            singleButtonlink: function (column, buttons, value, row, index, type) {
                var table = column.table;
                type = typeof type === 'undefined' ? 'buttons' : type;
                var options = table ? table.bootstrapTable('getOptions') : {};
                var html = [];
                var hidden, visible, url, classname, icon, text, title, refresh, confirm, extend;
                var fieldIndex = column.fieldIndex;

                $.each(buttons, function (i, j) {
                    if (type === 'operate') {
                        if (j.name === 'dragsort' && typeof row[Table.config.dragsortfield] === 'undefined') {
                            return true;
                        }
                        if (['add', 'edit', 'del', 'multi', 'dragsort'].indexOf(j.name) > -1 && !options.extend[j.name + "_url"]) {
                            return true;
                        }
                    }
                    var attr = table.data(type + "-" + j.name);
                    if (typeof attr === 'undefined' || attr) {
                        hidden = typeof j.hidden === 'function' ? j.hidden.call(table, row, j) : (j.hidden ? j.hidden : false);
                        if (hidden) {
                            return true;
                        }
                        visible = typeof j.visible === 'function' ? j.visible.call(table, row, j) : (j.visible ? j.visible : true);
                        if (!visible) {
                            return true;
                        }
                        url = j.url ? j.url : '';
                        url = typeof url === 'function' ? url.call(table, row, j) : (url ? Fast.api.fixurl(Table.api.replaceurl(url, row, table)) : 'javascript:;');
                        classname = j.classname ? j.classname : 'btn-primary btn-' + name + 'one';
                        icon = j.icon ? j.icon : '';
                        text = j.text ? j.text : '';
                        title = j.title ? j.title : text;
                        refresh = j.refresh ? 'data-refresh="' + j.refresh + '"' : '';
                        confirm = j.confirm ? 'data-confirm="' + j.confirm + '"' : '';
                        extend = j.extend ? j.extend : '';
                        html.push('<div class="single-button"><a href="' + url + '" class="' + classname + '" ' + (confirm ? confirm + ' ' : '') + (refresh ? refresh + ' ' : '') + extend + ' title="' + title + '" data-table-id="' + (table ? table.attr("id") : '') + '" data-field-index="' + fieldIndex + '" data-row-index="' + index + '" data-button-index="' + i + '"><i class="' + icon + '"></i>' + (text ? ' ' + text : '') + '</a></div>');
                    }
                });
                return html.join(' ');
            },
            //替换URL中的数据
            replaceurl: function (url, row, table) {
                var options = table ? table.bootstrapTable('getOptions') : null;
                var ids = options ? row[options.pk] : 0;
                row.ids = ids ? ids : (typeof row.ids !== 'undefined' ? row.ids : 0);
                //自动添加ids参数
                url = !url.match(/\{ids\}/i) ? url + (url.match(/(\?|&)+/) ? "&ids=" : "/ids/") + '{ids}' : url;
                url = url.replace(/\{(.*?)\}/gi, function (matched) {
                    matched = matched.substring(1, matched.length - 1);
                    if (matched.indexOf(".") !== -1) {
                        var temp = row;
                        var arr = matched.split(/\./);
                        for (var i = 0; i < arr.length; i++) {
                            if (typeof temp[arr[i]] !== 'undefined') {
                                temp = temp[arr[i]];
                            }
                        }
                        return typeof temp === 'object' ? '' : temp;
                    }
                    return row[matched];
                });
                return url;
            },
            // 获取选中的条目ID集合
            selectedids: function (table) {
                var options = table.bootstrapTable('getOptions');
                if (options.templateView) {
                    return $.map($("input[data-id][name='checkbox']:checked"), function (dom) {
                        return $(dom).data("id");
                    });
                } else {
                    return $.map(table.bootstrapTable('getSelections'), function (row) {
                        return row[options.pk];
                    });
                }
            },
            // 切换复选框状态
            toggleattr: function (table) {
                $("input[type='checkbox']", table).trigger('click');
            },
            // 根据行索引获取行数据
            getrowdata: function (table, index) {
                index = parseInt(index);
                var data = table.bootstrapTable('getData');
                return typeof data[index] !== 'undefined' ? data[index] : null;
            },
            // 根据行索引获取行数据
            getrowbyindex: function (table, index) {
                return Table.api.getrowdata(table, index);
            },
            // 根据主键ID获取行数据
            getrowbyid: function (table, id) {
                var row = {};
                var options = table.bootstrapTable("getOptions");
                $.each(table.bootstrapTable('getData'), function (i, j) {
                    if (j[options.pk] == id) {
                        row = j;
                        return false;
                    }
                });
                return row;
            }
        },
    };
    return Table;
});

// jQuery List DragSort v0.5.2
// Website: http://dragsort.codeplex.com/
// License: http://dragsort.codeplex.com/license

(function ($) {

    $.fn.dragsort = function (options) {
        if (options == "destroy") {
            $(this.selector).trigger("dragsort-uninit");
            return;
        }

        var opts = $.extend({}, $.fn.dragsort.defaults, options);
        var lists = [];
        var list = null,
            lastPos = null;

        this.each(function (i, cont) {

            //if list container is table, the browser automatically wraps rows in tbody if not specified so change list container to tbody so that children returns rows as user expected
            if ($(cont).is("table") && $(cont).children().size() == 1 && $(cont).children().is("tbody"))
                cont = $(cont).children().get(0);

            var newList = {
                draggedItem: null,
                placeHolderItem: null,
                pos: null,
                offset: null,
                offsetLimit: null,
                scroll: null,
                container: cont,

                init: function () {
                    //set options to default values if not set
                    opts.tagName = opts.tagName == "" ? ($(this.container).children().size() == 0 ? "li" : $(this.container).children().get(0).tagName.toLowerCase()) : opts.tagName;
                    if (opts.itemSelector == "")
                        opts.itemSelector = opts.tagName;
                    if (opts.dragSelector == "")
                        opts.dragSelector = opts.tagName;
                    if (opts.placeHolderTemplate == "")
                        opts.placeHolderTemplate = "<" + opts.tagName + ">&nbsp;</" + opts.tagName + ">";

                    //listidx allows reference back to correct list variable instance
                    $(this.container).attr("data-listidx", i).mousedown(this.grabItem).bind("dragsort-uninit", this.uninit);
                    this.styleDragHandlers(true);
                },

                uninit: function () {
                    var list = lists[$(this).attr("data-listidx")];
                    $(list.container).unbind("mousedown", list.grabItem).unbind("dragsort-uninit");
                    list.styleDragHandlers(false);
                },

                getItems: function () {
                    return $(this.container).children(opts.itemSelector);
                },

                styleDragHandlers: function (cursor) {
                    this.getItems().map(function () {
                        return $(this).is(opts.dragSelector) ? this : $(this).find(opts.dragSelector).get();
                    }).css("cursor", cursor ? "pointer" : "");
                },

                grabItem: function (e) {
                    var list = lists[$(this).attr("data-listidx")];
                    var item = $(e.target).closest("[data-listidx] > " + opts.tagName).get(0);
                    var insideMoveableItem = list.getItems().filter(function () {
                        return this == item;
                    }).size() > 0;

                    //if not left click or if clicked on excluded element (e.g. text box) or not a moveable list item return
                    if (e.which != 1 || $(e.target).is(opts.dragSelectorExclude) || $(e.target).closest(opts.dragSelectorExclude).size() > 0 || !insideMoveableItem)
                        return;

                    //prevents selection, stops issue on Fx where dragging hyperlink doesn't work and on IE where it triggers mousemove even though mouse hasn't moved,
                    //does also stop being able to click text boxes hence dragging on text boxes by default is disabled in dragSelectorExclude
                    //e.preventDefault();

                    //change cursor to move while dragging
                    var dragHandle = e.target;
                    while (!$(dragHandle).is(opts.dragSelector)) {
                        if (dragHandle == this) return;
                        dragHandle = dragHandle.parentNode;
                    }
                    $(dragHandle).attr("data-cursor", $(dragHandle).css("cursor"));
                    $(dragHandle).css("cursor", "move");

                    //on mousedown wait for movement of mouse before triggering dragsort script (dragStart) to allow clicking of hyperlinks to work
                    var listElem = this;
                    var trigger = function () {
                        list.dragStart.call(listElem, e);
                        $(list.container).unbind("mousemove", trigger);
                    };
                    $(list.container).mousemove(trigger).mouseup(function () {
                        $(list.container).unbind("mousemove", trigger);
                        $(dragHandle).css("cursor", $(dragHandle).attr("data-cursor"));
                    });
                },

                dragStart: function (e) {
                    if (list != null && list.draggedItem != null)
                        list.dropItem();

                    list = lists[$(this).attr("data-listidx")];
                    list.draggedItem = $(e.target).closest("[data-listidx] > " + opts.tagName)

                    //record current position so on dragend we know if the dragged item changed position or not, not using getItems to allow dragsort to restore dragged item to original location in relation to fixed items
                    list.draggedItem.attr("data-origpos", $(this).attr("data-listidx") + "-" + $(list.container).children().index(list.draggedItem));

                    //calculate mouse offset relative to draggedItem
                    var mt = parseInt(list.draggedItem.css("marginTop"));
                    var ml = parseInt(list.draggedItem.css("marginLeft"));
                    list.offset = list.draggedItem.offset();
                    list.offset.top = e.pageY - list.offset.top + (isNaN(mt) ? 0 : mt) - 1;
                    list.offset.left = e.pageX - list.offset.left + (isNaN(ml) ? 0 : ml) - 1;

                    //calculate box the dragged item can't be dragged outside of
                    if (!opts.dragBetween) {
                        var containerHeight = $(list.container).outerHeight() == 0 ? Math.max(1, Math.round(0.5 + list.getItems().size() * list.draggedItem.outerWidth() / $(list.container).outerWidth())) * list.draggedItem.outerHeight() : $(list.container).outerHeight();
                        list.offsetLimit = $(list.container).offset();
                        list.offsetLimit.right = list.offsetLimit.left + $(list.container).outerWidth() - list.draggedItem.outerWidth();
                        list.offsetLimit.bottom = list.offsetLimit.top + containerHeight - list.draggedItem.outerHeight();
                    }

                    //create placeholder item
                    var h = list.draggedItem.height();
                    var w = list.draggedItem.width();
                    if (opts.tagName == "tr") {
                        list.draggedItem.children().each(function () {
                            $(this).width($(this).width());
                        });
                        list.placeHolderItem = list.draggedItem.clone().attr("data-placeholder", true);
                        list.draggedItem.after(list.placeHolderItem);
                        //list.placeHolderItem.children().each(function() { $(this).css({ borderWidth:0, width: $(this).width() + 1, height: $(this).height() + 1 }).html("&nbsp;"); });
                        list.placeHolderItem.children().each(function () {
                            $(this).html("&nbsp;");
                        });
                    } else {
                        list.draggedItem.after(opts.placeHolderTemplate);
                        list.placeHolderItem = list.draggedItem.next().css({
                            height: h,
                            width: w
                        }).attr("data-placeholder", true);
                    }

                    if (opts.tagName == "td") {
                        var listTable = list.draggedItem.closest("table").get(0);
                        $("<table id='" + listTable.id + "' style='border-width: 0px;' class='dragSortItem " + listTable.className + "'><tr></tr></table>").appendTo("body").children().append(list.draggedItem);
                    }

                    //style draggedItem while dragging
                    var orig = list.draggedItem.attr("style");
                    list.draggedItem.attr("data-origstyle", orig ? orig : "");
                    list.draggedItem.css({
                        position: "absolute",
                        opacity: 0.8,
                        "z-index": 999,
                        height: h,
                        width: w
                    });

                    //auto-scroll setup
                    list.scroll = {
                        moveX: 0,
                        moveY: 0,
                        maxX: $(document).width() - $(window).width(),
                        maxY: $(document).height() - $(window).height()
                    };
                    list.scroll.scrollY = window.setInterval(function () {
                        if (opts.scrollContainer != window) {
                            $(opts.scrollContainer).scrollTop($(opts.scrollContainer).scrollTop() + list.scroll.moveY);
                            return;
                        }
                        var t = $(opts.scrollContainer).scrollTop();
                        if (list.scroll.moveY > 0 && t < list.scroll.maxY || list.scroll.moveY < 0 && t > 0) {
                            $(opts.scrollContainer).scrollTop(t + list.scroll.moveY);
                            list.draggedItem.css("top", list.draggedItem.offset().top + list.scroll.moveY + 1);
                        }
                    }, 10);
                    list.scroll.scrollX = window.setInterval(function () {
                        if (opts.scrollContainer != window) {
                            $(opts.scrollContainer).scrollLeft($(opts.scrollContainer).scrollLeft() + list.scroll.moveX);
                            return;
                        }
                        var l = $(opts.scrollContainer).scrollLeft();
                        if (list.scroll.moveX > 0 && l < list.scroll.maxX || list.scroll.moveX < 0 && l > 0) {
                            $(opts.scrollContainer).scrollLeft(l + list.scroll.moveX);
                            list.draggedItem.css("left", list.draggedItem.offset().left + list.scroll.moveX + 1);
                        }
                    }, 10);

                    //misc
                    $(lists).each(function (i, l) {
                        l.createDropTargets();
                        l.buildPositionTable();
                    });
                    list.setPos(e.pageX, e.pageY);
                    $(document).bind("mousemove", list.swapItems);
                    $(document).bind("mouseup", list.dropItem);
                    if (opts.scrollContainer != window)
                        $(window).bind("wheel", list.wheel);
                },

                //set position of draggedItem
                setPos: function (x, y) {
                    //remove mouse offset so mouse cursor remains in same place on draggedItem instead of top left corner
                    var top = y - this.offset.top;
                    var left = x - this.offset.left;

                    //limit top, left to within box draggedItem can't be dragged outside of
                    if (!opts.dragBetween) {
                        top = Math.min(this.offsetLimit.bottom, Math.max(top, this.offsetLimit.top));
                        left = Math.min(this.offsetLimit.right, Math.max(left, this.offsetLimit.left));
                    }

                    //adjust top & left calculations to parent offset
                    var parent = this.draggedItem.offsetParent().not("body").offset(); //offsetParent returns body even when it's static, if not static offset is only factoring margin
                    if (parent != null) {
                        top -= parent.top;
                        left -= parent.left;
                    }

                    //set x or y auto-scroll amount
                    if (opts.scrollContainer == window) {
                        y -= $(window).scrollTop();
                        x -= $(window).scrollLeft();
                        y = Math.max(0, y - $(window).height() + 5) + Math.min(0, y - 5);
                        x = Math.max(0, x - $(window).width() + 5) + Math.min(0, x - 5);
                    } else {
                        var cont = $(opts.scrollContainer);
                        var offset = cont.offset();
                        y = Math.max(0, y - cont.height() - offset.top) + Math.min(0, y - offset.top);
                        x = Math.max(0, x - cont.width() - offset.left) + Math.min(0, x - offset.left);
                    }

                    list.scroll.moveX = x == 0 ? 0 : x * opts.scrollSpeed / Math.abs(x);
                    list.scroll.moveY = y == 0 ? 0 : y * opts.scrollSpeed / Math.abs(y);

                    //move draggedItem to new mouse cursor location
                    this.draggedItem.css({
                        top: top,
                        left: left
                    });
                },

                //if scroll container is a div allow mouse wheel to scroll div instead of window when mouse is hovering over
                wheel: function (e) {
                    if (list && opts.scrollContainer != window) {
                        var cont = $(opts.scrollContainer);
                        var offset = cont.offset();
                        e = e.originalEvent;
                        if (e.clientX > offset.left && e.clientX < offset.left + cont.width() && e.clientY > offset.top && e.clientY < offset.top + cont.height()) {
                            var deltaY = (e.deltaMode == 0 ? 1 : 10) * e.deltaY;
                            cont.scrollTop(cont.scrollTop() + deltaY);
                            e.preventDefault();
                        }
                    }
                },

                //build a table recording all the positions of the moveable list items
                buildPositionTable: function () {
                    var pos = [];
                    this.getItems().not([list.draggedItem[0], list.placeHolderItem[0]]).each(function (i) {
                        var loc = $(this).offset();
                        loc.right = loc.left + $(this).outerWidth();
                        loc.bottom = loc.top + $(this).outerHeight();
                        loc.elm = this;
                        pos[i] = loc;
                    });
                    this.pos = pos;
                },

                dropItem: function () {
                    if (list.draggedItem == null)
                        return;

                    //list.draggedItem.attr("style", "") doesn't work on IE8 and jQuery 1.5 or lower
                    //list.draggedItem.removeAttr("style") doesn't work on chrome and jQuery 1.6 (works jQuery 1.5 or lower)
                    var orig = list.draggedItem.attr("data-origstyle");
                    list.draggedItem.attr("style", orig);
                    if (orig == "")
                        list.draggedItem.removeAttr("style");
                    list.draggedItem.removeAttr("data-origstyle");

                    list.styleDragHandlers(true);

                    list.placeHolderItem.before(list.draggedItem);
                    list.placeHolderItem.remove();

                    $("[data-droptarget], .dragSortItem").remove();

                    window.clearInterval(list.scroll.scrollY);
                    window.clearInterval(list.scroll.scrollX);

                    //if position changed call dragEnd
                    if (list.draggedItem.attr("data-origpos") != $(lists).index(list) + "-" + $(list.container).children().index(list.draggedItem))
                        if (opts.dragEnd.apply(list.draggedItem) == false) { //if dragEnd returns false revert order
                            var pos = list.draggedItem.attr("data-origpos").split('-');
                            var nextItem = $(lists[pos[0]].container).children().not(list.draggedItem).eq(pos[1]);
                            if (nextItem.size() > 0)
                                nextItem.before(list.draggedItem);
                            else if (pos[1] == 0) //was the only item in list
                                $(lists[pos[0]].container).prepend(list.draggedItem);
                            else //was the last item in list
                                $(lists[pos[0]].container).append(list.draggedItem);
                        }
                    list.draggedItem.removeAttr("data-origpos");

                    list.draggedItem = null;
                    $(document).unbind("mousemove", list.swapItems);
                    $(document).unbind("mouseup", list.dropItem);
                    if (opts.scrollContainer != window)
                        $(window).unbind("wheel", list.wheel);
                    return false;
                },

                //swap the draggedItem (represented visually by placeholder) with the list item the it has been dragged on top of
                swapItems: function (e) {
                    if (list.draggedItem == null)
                        return false;

                    //move draggedItem to mouse location
                    list.setPos(e.pageX, e.pageY);

                    //retrieve list and item position mouse cursor is over
                    var ei = list.findPos(e.pageX, e.pageY);
                    var nlist = list;
                    for (var i = 0; ei == -1 && opts.dragBetween && i < lists.length; i++) {
                        ei = lists[i].findPos(e.pageX, e.pageY);
                        nlist = lists[i];
                    }

                    //if not over another moveable list item return
                    if (ei == -1)
                        return false;

                    //save fixed items locations
                    var children = function () {
                        return $(nlist.container).children().not(nlist.draggedItem);
                    };
                    var fixed = children().not(opts.itemSelector).each(function (i) {
                        this.idx = children().index(this);
                    });

                    //if moving draggedItem up or left place placeHolder before list item the dragged item is hovering over otherwise place it after
                    if (lastPos == null || lastPos.top > list.draggedItem.offset().top || lastPos.left > list.draggedItem.offset().left)
                        $(nlist.pos[ei].elm).before(list.placeHolderItem);
                    else
                        $(nlist.pos[ei].elm).after(list.placeHolderItem);

                    //restore fixed items location
                    fixed.each(function () {
                        var elm = children().eq(this.idx).get(0);
                        if (this != elm && children().index(this) < this.idx)
                            $(this).insertAfter(elm);
                        else if (this != elm)
                            $(this).insertBefore(elm);
                    });

                    //misc
                    $(lists).each(function (i, l) {
                        l.createDropTargets();
                        l.buildPositionTable();
                    });
                    lastPos = list.draggedItem.offset();
                    return false;
                },

                //returns the index of the list item the mouse is over
                findPos: function (x, y) {
                    for (var i = 0; i < this.pos.length; i++) {
                        if (this.pos[i].left < x && this.pos[i].right > x && this.pos[i].top < y && this.pos[i].bottom > y)
                            return i;
                    }
                    return -1;
                },

                //create drop targets which are placeholders at the end of other lists to allow dragging straight to the last position
                createDropTargets: function () {
                    if (!opts.dragBetween)
                        return;

                    $(lists).each(function () {
                        var ph = $(this.container).find("[data-placeholder]");
                        var dt = $(this.container).find("[data-droptarget]");
                        if (ph.size() > 0 && dt.size() > 0)
                            dt.remove();
                        else if (ph.size() == 0 && dt.size() == 0) {
                            if (opts.tagName == "td")
                                $(opts.placeHolderTemplate).attr("data-droptarget", true).appendTo(this.container);
                            else
                                //list.placeHolderItem.clone().removeAttr("data-placeholder") crashes in IE7 and jquery 1.5.1 (doesn't in jquery 1.4.2 or IE8)
                                $(this.container).append(list.placeHolderItem.removeAttr("data-placeholder").clone().attr("data-droptarget", true));

                            list.placeHolderItem.attr("data-placeholder", true);
                        }
                    });
                }
            };

            newList.init();
            lists.push(newList);
        });

        return this;
    };

    $.fn.dragsort.defaults = {
        tagName: "",
        itemSelector: "",
        dragSelector: "",
        dragSelectorExclude: "input, textarea",
        dragEnd: function () {},
        dragBetween: false,
        placeHolderTemplate: "",
        scrollContainer: window,
        scrollSpeed: 5
    };

})(jQuery);

define("dragsort", function () {});

/*! 
 * jquery.event.drag - v 2.2
 * Copyright (c) 2010 Three Dub Media - http://threedubmedia.com
 * Open Source MIT License - http://threedubmedia.com/code/license
 */
;
(function (e) {
    e.fn.drag = function (k, g, j) {
        var i = typeof k == "string" ? k : "",
            h = e.isFunction(k) ? k : e.isFunction(g) ? g : null;
        if (i.indexOf("drag") !== 0) {
            i = "drag" + i
        }
        j = (k == h ? g : j) || {};
        return h ? this.bind(i, j, h) : this.trigger(i)
    };
    var b = e.event,
        a = b.special,
        d = a.drag = {
            defaults: {
                which: 1,
                distance: 0,
                not: ":input",
                handle: null,
                relative: false,
                drop: true,
                click: false
            },
            datakey: "dragdata",
            noBubble: true,
            add: function (i) {
                var h = e.data(this, d.datakey),
                    g = i.data || {};
                h.related += 1;
                e.each(d.defaults, function (j, k) {
                    if (g[j] !== undefined) {
                        h[j] = g[j]
                    }
                })
            },
            remove: function () {
                e.data(this, d.datakey).related -= 1
            },
            setup: function () {
                if (e.data(this, d.datakey)) {
                    return
                }
                var g = e.extend({
                    related: 0
                }, d.defaults);
                e.data(this, d.datakey, g);
                b.add(this, "touchstart mousedown", d.init, g);
                if (this.attachEvent) {
                    this.attachEvent("ondragstart", d.dontstart)
                }
            },
            teardown: function () {
                var g = e.data(this, d.datakey) || {};
                if (g.related) {
                    return
                }
                e.removeData(this, d.datakey);
                b.remove(this, "touchstart mousedown", d.init);
                d.textselect(true);
                if (this.detachEvent) {
                    this.detachEvent("ondragstart", d.dontstart)
                }
            },
            init: function (i) {
                if (d.touched) {
                    return
                }
                var g = i.data,
                    h;
                if (i.which != 0 && g.which > 0 && i.which != g.which) {
                    return
                }
                if (e(i.target).is(g.not)) {
                    return
                }
                if (g.handle && !e(i.target).closest(g.handle, i.currentTarget).length) {
                    return
                }
                d.touched = i.type == "touchstart" ? this : null;
                g.propagates = 1;
                g.mousedown = this;
                g.interactions = [d.interaction(this, g)];
                g.target = i.target;
                g.pageX = i.pageX;
                g.pageY = i.pageY;
                g.dragging = null;
                h = d.hijack(i, "draginit", g);
                if (!g.propagates) {
                    return
                }
                h = d.flatten(h);
                if (h && h.length) {
                    g.interactions = [];
                    e.each(h, function () {
                        g.interactions.push(d.interaction(this, g))
                    })
                }
                g.propagates = g.interactions.length;
                if (g.drop !== false && a.drop) {
                    a.drop.handler(i, g)
                }
                d.textselect(false);
                if (d.touched) {
                    b.add(d.touched, "touchmove touchend", d.handler, g)
                } else {
                    b.add(document, "mousemove mouseup", d.handler, g)
                }
                if (!d.touched || g.live) {
                    return false
                }
            },
            interaction: function (h, g) {
                var i = e(h)[g.relative ? "position" : "offset"]() || {
                    top: 0,
                    left: 0
                };
                return {
                    drag: h,
                    callback: new d.callback(),
                    droppable: [],
                    offset: i
                }
            },
            handler: function (h) {
                var g = h.data;
                switch (h.type) {
                    case !g.dragging && "touchmove":
                        h.preventDefault();
                    case !g.dragging && "mousemove":
                        if (Math.pow(h.pageX - g.pageX, 2) + Math.pow(h.pageY - g.pageY, 2) < Math.pow(g.distance, 2)) {
                            break
                        }
                        h.target = g.target;
                        d.hijack(h, "dragstart", g);
                        if (g.propagates) {
                            g.dragging = true
                        }
                        case "touchmove":
                            h.preventDefault();
                        case "mousemove":
                            if (g.dragging) {
                                d.hijack(h, "drag", g);
                                if (g.propagates) {
                                    if (g.drop !== false && a.drop) {
                                        a.drop.handler(h, g)
                                    }
                                    break
                                }
                                h.type = "mouseup"
                            }
                            case "touchend":
                            case "mouseup":
                            default:
                                if (d.touched) {
                                    b.remove(d.touched, "touchmove touchend", d.handler)
                                } else {
                                    b.remove(document, "mousemove mouseup", d.handler)
                                }
                                if (g.dragging) {
                                    if (g.drop !== false && a.drop) {
                                        a.drop.handler(h, g)
                                    }
                                    d.hijack(h, "dragend", g)
                                }
                                d.textselect(true);
                                if (g.click === false && g.dragging) {
                                    e.data(g.mousedown, "suppress.click", new Date().getTime() + 5)
                                }
                                g.dragging = d.touched = false;
                                break
                }
            },
            hijack: function (h, o, r, p, k) {
                if (!r) {
                    return
                }
                var q = {
                        event: h.originalEvent,
                        type: h.type
                    },
                    m = o.indexOf("drop") ? "drag" : "drop",
                    t, l = p || 0,
                    j, g, s, n = !isNaN(p) ? p : r.interactions.length;
                h.type = o;
                h.originalEvent = null;
                r.results = [];
                do {
                    if (j = r.interactions[l]) {
                        if (o !== "dragend" && j.cancelled) {
                            continue
                        }
                        s = d.properties(h, r, j);
                        j.results = [];
                        e(k || j[m] || r.droppable).each(function (u, i) {
                            s.target = i;
                            h.isPropagationStopped = function () {
                                return false
                            };
                            t = i ? b.dispatch.call(i, h, s) : null;
                            if (t === false) {
                                if (m == "drag") {
                                    j.cancelled = true;
                                    r.propagates -= 1
                                }
                                if (o == "drop") {
                                    j[m][u] = null
                                }
                            } else {
                                if (o == "dropinit") {
                                    j.droppable.push(d.element(t) || i)
                                }
                            }
                            if (o == "dragstart") {
                                j.proxy = e(d.element(t) || j.drag)[0]
                            }
                            j.results.push(t);
                            delete h.result;
                            if (o !== "dropinit") {
                                return t
                            }
                        });
                        r.results[l] = d.flatten(j.results);
                        if (o == "dropinit") {
                            j.droppable = d.flatten(j.droppable)
                        }
                        if (o == "dragstart" && !j.cancelled) {
                            s.update()
                        }
                    }
                } while (++l < n);
                h.type = q.type;
                h.originalEvent = q.event;
                return d.flatten(r.results)
            },
            properties: function (i, g, h) {
                var j = h.callback;
                j.drag = h.drag;
                j.proxy = h.proxy || h.drag;
                j.startX = g.pageX;
                j.startY = g.pageY;
                j.deltaX = i.pageX - g.pageX;
                j.deltaY = i.pageY - g.pageY;
                j.originalX = h.offset.left;
                j.originalY = h.offset.top;
                j.offsetX = j.originalX + j.deltaX;
                j.offsetY = j.originalY + j.deltaY;
                j.drop = d.flatten((h.drop || []).slice());
                j.available = d.flatten((h.droppable || []).slice());
                return j
            },
            element: function (g) {
                if (g && (g.jquery || g.nodeType == 1)) {
                    return g
                }
            },
            flatten: function (g) {
                return e.map(g, function (h) {
                    return h && h.jquery ? e.makeArray(h) : h && h.length ? d.flatten(h) : h
                })
            },
            textselect: function (g) {
                e(document)[g ? "unbind" : "bind"]("selectstart", d.dontstart).css("MozUserSelect", g ? "" : "none");
                document.unselectable = g ? "off" : "on"
            },
            dontstart: function () {
                return false
            },
            callback: function () {}
        };
    d.callback.prototype = {
        update: function () {
            if (a.drop && this.available.length) {
                e.each(this.available, function (g) {
                    a.drop.locate(this, g)
                })
            }
        }
    };
    var f = b.dispatch;
    b.dispatch = function (g) {
        if (e.data(this, "suppress." + g.type) - new Date().getTime() > 0) {
            e.removeData(this, "suppress." + g.type);
            return
        }
        return f.apply(this, arguments)
    };
    var c = b.fixHooks.touchstart = b.fixHooks.touchmove = b.fixHooks.touchend = b.fixHooks.touchcancel = {
        props: "clientX clientY pageX pageY screenX screenY".split(" "),
        filter: function (h, i) {
            if (i) {
                var g = (i.touches && i.touches[0]) || (i.changedTouches && i.changedTouches[0]) || null;
                if (g) {
                    e.each(c.props, function (j, k) {
                        h[k] = g[k]
                    })
                }
            }
            return h
        }
    };
    a.draginit = a.dragstart = a.dragend = d
})(jQuery);
define("drag", function () {});

/*! 
 * jquery.event.drop - v 2.2
 * Copyright (c) 2010 Three Dub Media - http://threedubmedia.com
 * Open Source MIT License - http://threedubmedia.com/code/license
 */
;
(function (d) {
    d.fn.drop = function (i, e, h) {
        var g = typeof i == "string" ? i : "",
            f = d.isFunction(i) ? i : d.isFunction(e) ? e : null;
        if (g.indexOf("drop") !== 0) {
            g = "drop" + g
        }
        h = (i == f ? e : h) || {};
        return f ? this.bind(g, h, f) : this.trigger(g)
    };
    d.drop = function (e) {
        e = e || {};
        b.multi = e.multi === true ? Infinity : e.multi === false ? 1 : !isNaN(e.multi) ? e.multi : b.multi;
        b.delay = e.delay || b.delay;
        b.tolerance = d.isFunction(e.tolerance) ? e.tolerance : e.tolerance === null ? null : b.tolerance;
        b.mode = e.mode || b.mode || "intersect"
    };
    var c = d.event,
        a = c.special,
        b = d.event.special.drop = {
            multi: 1,
            delay: 20,
            mode: "overlap",
            targets: [],
            datakey: "dropdata",
            noBubble: true,
            add: function (f) {
                var e = d.data(this, b.datakey);
                e.related += 1
            },
            remove: function () {
                d.data(this, b.datakey).related -= 1
            },
            setup: function () {
                if (d.data(this, b.datakey)) {
                    return
                }
                var e = {
                    related: 0,
                    active: [],
                    anyactive: 0,
                    winner: 0,
                    location: {}
                };
                d.data(this, b.datakey, e);
                b.targets.push(this);
                return false
            },
            teardown: function () {
                var f = d.data(this, b.datakey) || {};
                if (f.related) {
                    return
                }
                d.removeData(this, b.datakey);
                var e = this;
                b.targets = d.grep(b.targets, function (g) {
                    return (g !== e)
                })
            },
            handler: function (g, e) {
                var f, h;
                if (!e) {
                    return
                }
                switch (g.type) {
                    case "mousedown":
                    case "touchstart":
                        h = d(b.targets);
                        if (typeof e.drop == "string") {
                            h = h.filter(e.drop)
                        }
                        h.each(function () {
                            var i = d.data(this, b.datakey);
                            i.active = [];
                            i.anyactive = 0;
                            i.winner = 0
                        });
                        e.droppable = h;
                        a.drag.hijack(g, "dropinit", e);
                        break;
                    case "mousemove":
                    case "touchmove":
                        b.event = g;
                        if (!b.timer) {
                            b.tolerate(e)
                        }
                        break;
                    case "mouseup":
                    case "touchend":
                        b.timer = clearTimeout(b.timer);
                        if (e.propagates) {
                            a.drag.hijack(g, "drop", e);
                            a.drag.hijack(g, "dropend", e)
                        }
                        break
                }
            },
            locate: function (k, h) {
                var l = d.data(k, b.datakey),
                    g = d(k),
                    i = g.offset() || {},
                    e = g.outerHeight(),
                    j = g.outerWidth(),
                    f = {
                        elem: k,
                        width: j,
                        height: e,
                        top: i.top,
                        left: i.left,
                        right: i.left + j,
                        bottom: i.top + e
                    };
                if (l) {
                    l.location = f;
                    l.index = h;
                    l.elem = k
                }
                return f
            },
            contains: function (e, f) {
                return ((f[0] || f.left) >= e.left && (f[0] || f.right) <= e.right && (f[1] || f.top) >= e.top && (f[1] || f.bottom) <= e.bottom)
            },
            modes: {
                intersect: function (f, e, g) {
                    return this.contains(g, [f.pageX, f.pageY]) ? 1000000000 : this.modes.overlap.apply(this, arguments)
                },
                overlap: function (f, e, g) {
                    return Math.max(0, Math.min(g.bottom, e.bottom) - Math.max(g.top, e.top)) * Math.max(0, Math.min(g.right, e.right) - Math.max(g.left, e.left))
                },
                fit: function (f, e, g) {
                    return this.contains(g, e) ? 1 : 0
                },
                middle: function (f, e, g) {
                    return this.contains(g, [e.left + e.width * 0.5, e.top + e.height * 0.5]) ? 1 : 0
                }
            },
            sort: function (f, e) {
                return (e.winner - f.winner) || (f.index - e.index)
            },
            tolerate: function (q) {
                var k, e, n, j, l, m, g, p = 0,
                    f, h = q.interactions.length,
                    r = [b.event.pageX, b.event.pageY],
                    o = b.tolerance || b.modes[b.mode];
                do {
                    if (f = q.interactions[p]) {
                        if (!f) {
                            return
                        }
                        f.drop = [];
                        l = [];
                        m = f.droppable.length;
                        if (o) {
                            n = b.locate(f.proxy)
                        }
                        k = 0;
                        do {
                            if (g = f.droppable[k]) {
                                j = d.data(g, b.datakey);
                                e = j.location;
                                if (!e) {
                                    continue
                                }
                                j.winner = o ? o.call(b, b.event, n, e) : b.contains(e, r) ? 1 : 0;
                                l.push(j)
                            }
                        } while (++k < m);
                        l.sort(b.sort);
                        k = 0;
                        do {
                            if (j = l[k]) {
                                if (j.winner && f.drop.length < b.multi) {
                                    if (!j.active[p] && !j.anyactive) {
                                        if (a.drag.hijack(b.event, "dropstart", q, p, j.elem)[0] !== false) {
                                            j.active[p] = 1;
                                            j.anyactive += 1
                                        } else {
                                            j.winner = 0
                                        }
                                    }
                                    if (j.winner) {
                                        f.drop.push(j.elem)
                                    }
                                } else {
                                    if (j.active[p] && j.anyactive == 1) {
                                        a.drag.hijack(b.event, "dropend", q, p, j.elem);
                                        j.active[p] = 0;
                                        j.anyactive -= 1
                                    }
                                }
                            }
                        } while (++k < m)
                    }
                } while (++p < h);
                if (b.last && r[0] == b.last.pageX && r[1] == b.last.pageY) {
                    delete b.timer
                } else {
                    b.timer = setTimeout(function () {
                        b.tolerate(q)
                    }, b.delay)
                }
                b.last = b.event
            }
        };
    a.dropinit = a.dropstart = a.dropend = b
})(jQuery);
define("drop", function () {});

/**
 * http://git.oschina.net/hbbcs/bootStrap-addTabs
 * Created by joe on 2015-12-19.
 * Modified by Karson
 */

(function ($) {

    $.fn.addtabs = function (options) {
        var obj = $(this);
        options = $.extend({
            content: '', //直接指定所有页面TABS内容
            close: true, //是否可以关闭
            monitor: 'body', //监视的区域
            nav: '.nav-addtabs',
            tab: '.tab-addtabs',
            iframeUse: true, //使用iframe还是ajax
            iframeHeight: $(window).height() - 50, //固定TAB中IFRAME高度,根据需要自己修改
            iframeForceRefresh: false, //点击后强制刷新对应的iframe
            callback: function () {
                //关闭后回调函数
            }
        }, options || {});
        var navobj = $(options.nav);
        var tabobj = $(options.tab);
        if (history.pushState) {
            //浏览器前进后退事件
            $(window).on("popstate", function (e) {
                var state = e.originalEvent.state;
                if (state) {
                    $("a[addtabs=" + state.id + "]", options.monitor).data("pushstate", true).trigger("click");
                }
            });
        }
        $(options.monitor).on('click', '[addtabs]', function (e) {
            if ($(this).attr('url').indexOf("javascript:") !== 0) {
                if ($(this).is("a")) {
                    e.preventDefault();
                }
                var id = $(this).attr('addtabs');
                var title = $(this).attr('title') ? $(this).attr('title') : $.trim($(this).text());
                var url = $(this).attr('url');
                var content = options.content ? options.content : $(this).attr('content');
                var ajax = $(this).attr('ajax') === '1' || $(this).attr('ajax') === 'true';
                var state = ({
                    url: url,
                    title: title,
                    id: id,
                    content: content,
                    ajax: ajax
                });

                document.title = title;
                if (history.pushState && !$(this).data("pushstate")) {
                    var pushurl = url.indexOf("ref=addtabs") === -1 ? (url + (url.indexOf("?") > -1 ? "&" : "?") + "ref=addtabs") : url;
                    try {
                        window.history.pushState(state, title, pushurl);
                    } catch (e) {

                    }
                }
                $(this).data("pushstate", null);
                _add.call(this, {
                    id: id,
                    title: $(this).attr('title') ? $(this).attr('title') : $(this).html(),
                    content: content,
                    url: url,
                    ajax: ajax
                });
            }
        });

        navobj.on('click', '.close-tab', function () {
            var id = $(this).prev("a").attr("aria-controls");
            _close(id);
            return false;
        });
        navobj.on('dblclick', 'li[role=presentation]', function () {
            $(this).find(".close-tab").trigger("click");
        });
        navobj.on('click', 'li[role=presentation]', function () {
            $("a[addtabs=" + $("a", this).attr("node-id") + "]").trigger("click");
        });

        $(window).resize(function () {
            if (typeof options.nav === 'object') {
                var siblingsWidth = 0;
                navobj.siblings().each(function () {
                    siblingsWidth += $(this).outerWidth();
                });
                navobj.width(navobj.parent().width() - siblingsWidth);
            } else {
                $("#nav").width($("#header").find("> .navbar").width() - $(".sidebar-toggle").outerWidth() - $(".navbar-custom-menu").outerWidth() - 20);
            }
            _drop();
        });

        var _add = function (opts) {
            var id, tabid, conid, url;
            id = opts.id;
            tabid = 'tab_' + opts.id;
            conid = 'con_' + opts.id;
            url = opts.url;
            url += (opts.url.indexOf("?") > -1 ? "&addtabs=1" : "?addtabs=1");

            var tabitem = $('#' + tabid, navobj);
            var conitem = $('#' + conid, tabobj);

            navobj.find("[role='presentation']").removeClass('active');
            tabobj.find("[role='tabpanel']").removeClass('active');

            //如果TAB不存在，创建一个新的TAB
            if (tabitem.size() === 0) {
                //创建新TAB的title
                tabitem = $('<li role="presentation" id="' + tabid + '"><a href="#' + conid + '" node-id="' + opts.id + '" aria-controls="' + id + '" role="tab" data-toggle="tab">' + opts.title + '</a></li>');
                //是否允许关闭
                if (options.close && $("li", navobj).size() > 0) {
                    tabitem.append(' <i class="close-tab fa fa-remove"></i>');
                }
                //创建新TAB的内容
                conitem = $('<div role="tabpanel" class="tab-pane" id="' + conid + '"></div>');
                //是否指定TAB内容
                if (opts.content) {
                    conitem.append(opts.content);
                } else if (options.iframeUse && !opts.ajax) { //没有内容，使用IFRAME打开链接
                    var height = options.iframeHeight;
                    conitem.append('<iframe src="' + url + '" width="100%" height="' + height + '" frameborder="no" border="0" marginwidth="0" marginheight="0" scrolling-x="no" scrolling-y="auto" allowtransparency="yes"></iframe></div>');
                } else {
                    $.get(url, function (data) {
                        conitem.append(data);
                    });
                }
                //加入TABS
                if ($('.tabdrop li', navobj).size() > 0) {
                    $('.tabdrop ul', navobj).append(tabitem);
                } else {
                    navobj.append(tabitem);
                }
                tabobj.append(conitem);
            } else {
                //强制刷新iframe
                if (options.iframeForceRefresh) {
                    $("#" + conid + " iframe").attr('src', function (i, val) {
                        return val;
                    });
                }
            }
            localStorage.setItem("addtabs", $(this).prop('outerHTML'));
            //激活TAB
            tabitem.addClass('active');
            conitem.addClass("active");
            _drop();
        };

        var _close = function (id) {
            var tabid = 'tab_' + id;
            var conid = 'con_' + id;
            var tabitem = $('#' + tabid, navobj);
            var conitem = $('#' + conid, tabobj);
            //如果关闭的是当前激活的TAB，激活他的前一个TAB
            if (obj.find("li.active").not('.tabdrop').attr('id') === tabid) {
                var prev = tabitem.prev().not(".tabdrop");
                var next = tabitem.next().not(".tabdrop");
                if (prev.size() > 0) {
                    prev.find('a').trigger("click");
                } else if (next.size() > 0) {
                    next.find('a').trigger("click");
                } else {
                    $(">li:not(.tabdrop):last > a", navobj).trigger('click');
                }
            }
            //关闭TAB
            tabitem.remove();
            conitem.remove();
            _drop();
            options.callback();
        };

        var _drop = function () {
            navobj.refreshAddtabs();
        };
    };
    //刷新Addtabs
    $.fn.refreshAddtabs = function () {
        var navobj = $(this);
        var dropdown = $(".tabdrop", navobj);
        if (dropdown.size() === 0) {
            dropdown = $('<li class="dropdown pull-right hide tabdrop"><a class="dropdown-toggle" data-toggle="dropdown" href="javascript:;">' +
                '<i class="glyphicon glyphicon-align-justify"></i>' +
                ' <b class="caret"></b></a><ul class="dropdown-menu"></ul></li>');
            dropdown.prependTo(navobj);
        }

        //检测是否有下拉样式
        if (navobj.parent().is('.tabs-below')) {
            dropdown.addClass('dropup');
        }

        var collection = 0;
        var maxwidth = navobj.width() - 65;

        var liwidth = 0;
        //检查超过一行的标签页
        var litabs = navobj.append(dropdown.find('li')).find('>li').not('.tabdrop');
        var totalwidth = 0;
        litabs.each(function () {
            totalwidth += $(this).outerWidth(true);
        });
        if (navobj.width() < totalwidth) {
            litabs.each(function () {
                liwidth += $(this).outerWidth(true);
                if (liwidth > maxwidth) {
                    dropdown.find('ul').append($(this));
                    collection++;
                }
            });
            if (collection > 0) {
                dropdown.removeClass('hide');
                if (dropdown.find('.active').length === 1) {
                    dropdown.addClass('active');
                } else {
                    dropdown.removeClass('active');
                }
            }
        } else {
            dropdown.addClass('hide');
        }

    };
})(jQuery);
define("addtabs", function () {});

/**
 * @summary     SelectPage
 * @desc        Simple and powerful selection plugin
 * @file        selectpage.js
 * @version     2.18
 * @author      TerryZeng
 * @contact     https://terryz.github.io/
 * @license     MIT License
 *
 */
;
(function ($) {
    "use strict";
    /**
     * Default options
     */
    var defaults = {
        /**
         * Data source
         * @type {string|Object}
         *
         * string：server side request url address
         * Object：JSON array，format：[{a:1,b:2,c:3},{...}]
         */
        data: undefined,
        /**
         * Language ('cn', 'en', 'ja', 'es', 'pt-br')
         * @type string
         * @default 'cn'
         */
        lang: 'cn',
        /**
         * Multiple select mode(tags)
         * @type boolean
         * @default false
         */
        multiple: false,
        /**
         * pagination or not
         * @type boolean
         * @default true
         */
        pagination: true,
        /**
         * Show up menu button
         * @type boolean
         * @default true
         */
        dropButton: true,
        /**
         * Result list visible size in pagination bar close
         * @type number
         * @default 10
         */
        listSize: 10,
        /**
         * Show control bar in multiple select mode
         * @type boolean
         * @default true
         */
        multipleControlbar: true,
        /**
         * Max selected item limited in multiple select mode
         * @type number
         * @default 0(unlimited)
         */
        maxSelectLimit: 0,
        /**
         * Select result item to close list, work on multiple select mode
         * @type boolean
         * @default false
         */
        selectToCloseList: false,
        /**
         * Init selected item key, the result will match to option.keyField option
         * @type string 
         */
        initRecord: undefined,
        /**
         * The table parameter in server side mode
         * @type string
         */
        dbTable: 'tbl',
        /**
         * The value field, the value will fill to hidden element
         * @type string
         * @default 'id'
         */
        keyField: 'id',
        /**
         * The show text field, the text will show to input element or tags(multiple mode)
         * @type string
         * @default 'name'
         */
        showField: 'name',
        /**
         * Actually used to search field
         * @type string
         */
        searchField: undefined,
        /**
         * Search type ('AND' or 'OR')
         * @type string
         * @default 'AND'
         */
        andOr: 'AND',
        /**
         * Result sort type
         * @type array - if not set, will default used showField field
         * @example
         * orderBy : ['id desc']
         */
        orderBy: undefined,
        /**
         * Page size
         * @type number
         * @default 10
         */
        pageSize: 10,
        /**
         * Server side request parameters
         * @type function
         * @return object
         * @example params : function(){return {'name':'aa','sex':1};}
         */
        params: undefined,
        /**
         * Custom result list item show text
         * @type function
         * @param data {object} row data
         * @return string
         */
        formatItem: undefined,
        /**
         * Have some highlight item and lost focus, auto select the highlight item
         * @type boolean
         * @default false
         */
        autoFillResult: false,
        /**
         * Auto select first item in show up result list or search result
         * depend on `autoFillResult` option set to true
         * @type boolean
         * @default false
         */
        autoSelectFirst: false,
        /**
         * Whether clear input element text when enter some keywords to search and no result return
         * @type boolean
         * @default true
         */
        noResultClean: true,
        /**
         * Select only mode
         * @type boolean
         */
        selectOnly: false,
        /**
         * Input to search delay time, work on ajax data source
         * @type number
         * @default 0.5
         */
        inputDelay: 0.5,
        /**
         * -----------------------------------------Callback--------------------------------------------
         */
        /**
         * Result list item selected callback
         * @type function
         * @param object - selected item json data
         * @param self   - plugin object
         */
        eSelect: undefined,
        /**
         * Before result list show up callback, you can do anything prepared
         * @param self - plugin object
         */
        eOpen: undefined,
        /**
         * Server side return data convert callback
         * @type function
         * @param data {object} server side return data
         * @param self {object} plugin object
         * @return {object} return data format：
         * @example 
         * {
         *   list : [{name:'aa',sex:1},{name:'bb',sex:1}...],
         *   totalRow : 100
         * }
         */
        eAjaxSuccess: undefined,
        /**
         * Close selected item tag callback (multiple mode)
         * @type function
         * @param removeCount {number} remove item count
         * @param self {object} plugin object
         */
        eTagRemove: undefined,
        /**
         * Clear selected item callback(single select mode)
         * @type function
         * @param self {object} plugin object
         */
        eClear: undefined
    };


    /**
     * SelectPage class definition
     * @constructor
     * @param {Object} input - input element
     * @param {Object} option
     */
    var SelectPage = function (input, option) {
        //特殊字段处理
        $.each({
            data: 'source',
            keyField: 'primaryKey',
            showField: 'field',
            pageSize: 'perPage'
        }, function (i, j) {
            if (typeof option[j] !== 'undefined') {
                option[i] = option[j];
                delete option[j];
            }
        });
        this.setOption(option);
        this.setLanguage();
        this.setCssClass();
        this.setProp();
        this.setElem(input);

        this.setButtonAttrDefault();
        this.setInitRecord();

        this.eDropdownButton();
        this.eInput();
        this.eWhole();
    };
    /**
     * Plugin version number
     */
    SelectPage.version = '2.18';
    /**
     * Plugin object cache key
     */
    SelectPage.dataKey = 'selectPageObject';
    /**
     * Options set
     * @param {Object} option
     */
    SelectPage.prototype.setOption = function (option) {
        //use showField to default
        option.searchField = option.searchField || option.showField;

        option.andOr = option.andOr.toUpperCase();
        if (option.andOr !== 'AND' && option.andOr !== 'OR')
            option.andOr = 'AND';

        //support multiple field set
        var arr = ['searchField'];
        for (var i = 0; i < arr.length; i++) {
            option[arr[i]] = this.strToArray(option[arr[i]]);
        }

        //set default order field
        option.orderBy = option.orderBy || option.showField;

        //set multiple order field
        //example:  [ ['id', 'ASC'], ['name', 'DESC'] ]
        option.orderBy = this.setOrderbyOption(option.orderBy, option.showField);
        //close auto fill result and auto select first in multiple mode and select item not close list
        if (option.multiple && !option.selectToCloseList) {
            option.autoFillResult = false;
            option.autoSelectFirst = false;
        }
        //show all item when pagination bar close, limited 200
        if (!option.pagination)
            option.pageSize = 200;
        if ($.type(option.listSize) !== 'number' || option.listSize < 0)
            option.listSize = 10;

        this.option = option;
    };

    /**
     * String convert to array
     * @param str {string}
     * @return {Array}
     */
    SelectPage.prototype.strToArray = function (str) {
        if (!str)
            return '';
        return str.replace(/[\s　]+/g, '').split(',');
    };

    /**
     * Set order field
     * @param {Array} arg_order
     * @param {string} arg_field
     * @return {Array}
     */
    SelectPage.prototype.setOrderbyOption = function (arg_order, arg_field) {
        var arr = [],
            orders = [];
        if (typeof arg_order == 'object') {
            for (var i = 0; i < arg_order.length; i++) {
                orders = $.trim(arg_order[i]).split(' ');
                arr[i] = (orders.length == 2) ? orders : [orders[0], 'ASC'];
            }
        } else {
            orders = $.trim(arg_order).split(' ');
            arr[0] = (orders.length == 2) ? orders : (orders[0].match(/^(ASC|DESC)$/i)) ? [arg_field, orders[0]] : [orders[0], 'ASC'];
        }
        return arr;
    };

    /**
     * i18n
     */
    SelectPage.prototype.setLanguage = function () {
        var message, p = this.option;
        switch (p.lang) {
            // English
            case 'en':
                message = {
                    add_btn: 'Add button',
                    add_title: 'add a box',
                    del_btn: 'Del button',
                    del_title: 'delete a box',
                    next: 'Next',
                    next_title: 'Next' + p.pageSize + ' (Right key)',
                    prev: 'Prev',
                    prev_title: 'Prev' + p.pageSize + ' (Left key)',
                    first_title: 'First (Shift + Left key)',
                    last_title: 'Last (Shift + Right key)',
                    get_all_btn: 'Get All (Down key)',
                    get_all_alt: '(button)',
                    close_btn: 'Close (Tab key)',
                    close_alt: '(button)',
                    loading: 'loading...',
                    loading_alt: '(loading)',
                    page_info: 'page_num of page_count',
                    select_ng: 'Attention : Please choose from among the list.',
                    select_ok: 'OK : Correctly selected.',
                    not_found: 'not found',
                    ajax_error: 'An error occurred while connecting to server.',
                    clear: 'Clear content',
                    select_all: 'Select current page',
                    unselect_all: 'Clear current page',
                    clear_all: 'Clear all selected',
                    max_selected: 'You can only select up to max_selected_limit items'
                };
                break;
                // 中文
            case 'cn':
            default:
                message = {
                    add_btn: '添加按钮',
                    add_title: '添加区域',
                    del_btn: '删除按钮',
                    del_title: '删除区域',
                    next: '下一页',
                    next_title: '下' + p.pageSize + ' (→)',
                    prev: '上一页',
                    prev_title: '上' + p.pageSize + ' (←)',
                    first_title: '首页 (Shift + ←)',
                    last_title: '尾页 (Shift + →)',
                    get_all_btn: '获得全部 (↓)',
                    get_all_alt: '(按钮)',
                    close_btn: '关闭 (Tab键)',
                    close_alt: '(按钮)',
                    loading: '读取中...',
                    loading_alt: '(读取中)',
                    page_info: '第 page_num 页(共page_count页)',
                    select_ng: '请注意：请从列表中选择.',
                    select_ok: 'OK : 已经选择.',
                    not_found: '无查询结果',
                    ajax_error: '连接到服务器时发生错误！',
                    clear: '清除内容',
                    select_all: '选择当前页项目',
                    unselect_all: '取消选择当前页项目',
                    clear_all: '清除全部已选择项目',
                    max_selected: '最多只能选择 max_selected_limit 个项目'
                };
                break;
        }
        this.message = message;
    };

    /**
     * Css classname defined
     */
    SelectPage.prototype.setCssClass = function () {
        var css_class = {
            container: 'sp_container',
            container_open: 'sp_container_open',
            re_area: 'sp_result_area',
            result_open: 'sp_result_area_open',
            control_box: 'sp_control_box',
            //multiple select mode
            element_box: 'sp_element_box',
            navi: 'sp_navi',
            //result list
            results: 'sp_results',
            re_off: 'sp_results_off',
            select: 'sp_over',
            select_ok: 'sp_select_ok',
            select_ng: 'sp_select_ng',
            selected: 'sp_selected',
            input_off: 'sp_input_off',
            message_box: 'sp_message_box',
            disabled: 'sp_disabled',

            button: 'sp_button',
            btn_on: 'sp_btn_on',
            btn_out: 'sp_btn_out',
            input: 'sp_input',
            clear_btn: 'sp_clear_btn',
            align_right: 'sp_align_right'
        };
        this.css_class = css_class;
    };

    /**
     * Plugin inner properties
     */
    SelectPage.prototype.setProp = function () {
        this.prop = {
            //input disabled status
            disabled: false,
            current_page: 1,
            //total page
            max_page: 1,
            //ajax data loading status
            is_loading: false,
            xhr: false,
            key_paging: false,
            key_select: false,
            //last selected item value
            prev_value: '',
            //last selected item text
            selected_text: '',
            last_input_time: undefined,
            init_set: false
        };
        this.template = {
            tag: {
                content: '<li class="selected_tag" itemvalue="#item_value#">#item_text#<span class="tag_close"><i class="spfont sp-close"></i></span></li>',
                textKey: '#item_text#',
                valueKey: '#item_value#'
            },
            page: {
                current: 'page_num',
                total: 'page_count'
            },
            msg: {
                maxSelectLimit: 'max_selected_limit'
            }
        };
    };

    /**
     * Get the actual width/height of invisible DOM elements with jQuery.
     * Source code come from dreamerslab/jquery.actual
     * @param element
     * @param method
     * @returns {*}
     */
    SelectPage.prototype.elementRealSize = function (element, method) {
        var defaults = {
            absolute: false,
            clone: false,
            includeMargin: false,
            display: 'block'
        };
        var configs = defaults,
            $target = element.eq(0),
            fix, restore, tmp = [],
            style = '',
            $hidden;

        fix = function () {
            // get all hidden parents
            $hidden = $target.parents().addBack().filter(':hidden');
            style += 'visibility: hidden !important; display: ' + configs.display + ' !important; ';

            if (configs.absolute === true)
                style += 'position: absolute !important;';

            // save the origin style props
            // set the hidden el css to be got the actual value later
            $hidden.each(function () {
                // Save original style. If no style was set, attr() returns undefined
                var $this = $(this),
                    thisStyle = $this.attr('style');
                tmp.push(thisStyle);
                // Retain as much of the original style as possible, if there is one
                $this.attr('style', thisStyle ? thisStyle + ';' + style : style);
            });
        };

        restore = function () {
            // restore origin style values
            $hidden.each(function (i) {
                var $this = $(this),
                    _tmp = tmp[i];

                if (_tmp === undefined)
                    $this.removeAttr('style');
                else
                    $this.attr('style', _tmp);
            });
        };

        fix();
        // get the actual value with user specific methed
        // it can be 'width', 'height', 'outerWidth', 'innerWidth'... etc
        // configs.includeMargin only works for 'outerWidth' and 'outerHeight'
        var actual = /(outer)/.test(method) ?
            $target[method](configs.includeMargin) :
            $target[method]();

        restore();
        // IMPORTANT, this plugin only return the value of the first element
        return actual;
    };

    /**
     * Dom building
     * @param {Object} combo_input - original input element
     */
    SelectPage.prototype.setElem = function (combo_input) {
        // 1. build Dom object
        var elem = {},
            p = this.option,
            css = this.css_class,
            msg = this.message,
            input = $(combo_input);
        var orgWidth = input.outerWidth();
        // fix input width in hidden situation
        if (orgWidth <= 0)
            orgWidth = this.elementRealSize(input, 'outerWidth');
        if (orgWidth < 150)
            orgWidth = 150;

        elem.combo_input = input.attr({
            'autocomplete': 'off'
        }).addClass(css.input).wrap('<div>');
        if (p.selectOnly)
            elem.combo_input.prop('readonly', true);
        elem.container = elem.combo_input.parent().addClass(css.container);
        if (elem.combo_input.prop('disabled')) {
            if (p.multiple)
                elem.container.addClass(css.disabled);
            else
                elem.combo_input.addClass(css.input_off);
        }

        // set outer box width
        elem.container.width(orgWidth);

        elem.button = $('<div>').addClass(css.button);
        //drop down button
        elem.dropdown = $('<span class="sp_caret"></span>');
        //clear button 'X' in single mode
        elem.clear_btn = $('<div>').html($('<i>').addClass('spfont sp-close')).addClass(css.clear_btn).attr('title', msg.clear);
        if (!p.dropButton)
            elem.clear_btn.addClass(css.align_right);

        //main box in multiple mode
        elem.element_box = $('<ul>').addClass(css.element_box);
        if (p.multiple && p.multipleControlbar)
            elem.control = $('<div>').addClass(css.control_box);
        //result list box
        elem.result_area = $('<div>').addClass(css.re_area);
        //pagination bar
        if (p.pagination)
            elem.navi = $('<div>').addClass('sp_pagination').append('<ul>');
        elem.results = $('<ul>').addClass(css.results);

        var namePrefix = '_text',
            input_id = elem.combo_input.attr('id') || elem.combo_input.attr('name'),
            input_name = elem.combo_input.attr('name') || 'selectPage',
            hidden_name = input_name,
            hidden_id = input_id;

        //switch the id and name attributes of input/hidden element
        elem.hidden = $('<input type="hidden" class="sp_hidden" />').attr({
            name: hidden_name,
            id: hidden_id
        }).val('');
        elem.combo_input.attr({
            name: input_name + namePrefix,
            id: input_id + namePrefix
        });

        // 2. DOM element put
        elem.container.append(elem.hidden);
        if (p.dropButton) {
            elem.container.append(elem.button)
            elem.button.append(elem.dropdown);
        }
        $(document.body).append(elem.result_area);
        elem.result_area.append(elem.results);
        if (p.pagination)
            elem.result_area.append(elem.navi);

        //Multiple select mode
        if (p.multiple) {
            if (p.multipleControlbar) {
                elem.control.append('<button type="button" class="btn btn-default sp_clear_all" ><i class="spfont sp-clear"></i></button>');
                elem.control.append('<button type="button" class="btn btn-default sp_unselect_all" ><i class="spfont sp-unselect-all"></i></button>');
                elem.control.append('<button type="button" class="btn btn-default sp_select_all" ><i class="spfont sp-select-all"></i></button>');
                elem.control_text = $('<p>');
                elem.control.append(elem.control_text);
                elem.result_area.prepend(elem.control);
            }
            elem.container.addClass('sp_container_combo');
            elem.combo_input.addClass('sp_combo_input').before(elem.element_box);
            var li = $('<li>').addClass('input_box');
            li.append(elem.combo_input);
            elem.element_box.append(li);
            if (elem.combo_input.attr('placeholder'))
                elem.combo_input.attr('placeholder_bak', elem.combo_input.attr('placeholder'));
        }

        this.elem = elem;
    };

    /**
     * Drop down button set to default
     */
    SelectPage.prototype.setButtonAttrDefault = function () {
        /*
         if (this.option.selectOnly) {
         if ($(this.elem.combo_input).val() !== '') {
         if ($(this.elem.hidden).val() !== '') {
         //选择条件
         $(this.elem.combo_input).attr('title', this.message.select_ok).removeClass(this.css_class.select_ng).addClass(this.css_class.select_ok);
         } else {
         //输入方式
         $(this.elem.combo_input).attr('title', this.message.select_ng).removeClass(this.css_class.select_ok).addClass(this.css_class.select_ng);
         }
         } else {
         $(this.elem.hidden).val('');
         $(this.elem.combo_input).removeAttr('title').removeClass(this.css_class.select_ng);
         }
         }
         */
        //this.elem.button.attr('title', this.message.get_all_btn);
        if (this.option.dropButton)
            this.elem.button.attr('title', this.message.close_btn);
    };

    /**
     * Set item need selected after init
     * set selected item ways:
     * <input value="key">
     * <input data-init="key">
     */
    SelectPage.prototype.setInitRecord = function (refresh) {
        var self = this,
            p = self.option,
            el = self.elem,
            key = '';
        if ($.type(el.combo_input.data('init')) != 'undefined')
            p.initRecord = String(el.combo_input.data('init'));
        //data-init and value attribute can be init plugin selected item
        //but, if set data-init and value attribute in the same time, plugin will choose data-init attribute first
        if (!refresh && !p.initRecord && el.combo_input.val())
            p.initRecord = el.combo_input.val();
        el.combo_input.val('');
        if (!refresh)
            el.hidden.val(p.initRecord);
        key = refresh && el.hidden.val() ? el.hidden.val() : p.initRecord;
        if (key) {
            if (typeof p.data === 'object') {
                var data = new Array();
                var keyarr = key.split(',');
                $.each(keyarr, function (index, row) {
                    for (var i = 0; i < p.data.length; i++) {
                        if (p.data[i][p.keyField] == row) {
                            data.push(p.data[i]);
                            break;
                        }
                    }
                });
                if (!p.multiple && data.length > 1)
                    data = [data[0]];
                self.afterInit(self, data);
            } else { //ajax data source mode to init selected item
                $.ajax({
                    dataType: 'json',
                    type: 'POST',
                    url: p.data,
                    data: {
                        searchTable: p.dbTable,
                        searchKey: p.keyField,
                        searchValue: key,
                        orderBy: p.orderBy,
                        showField: p.showField,
                        keyField: p.keyField,
                        keyValue: key,
                        searchField: p.searchField
                    },
                    success: function (json) {
                        var d = null;
                        if (p.eAjaxSuccess && $.isFunction(p.eAjaxSuccess))
                            d = p.eAjaxSuccess(json);
                        self.afterInit(self, d.list);
                    },
                    error: function (jqXHR, textStatus, errorThrown) {
                        self.ajaxErrorNotify(self, errorThrown);
                    }
                });
            }
        }
    };

    /**
     * Selected item set to plugin
     * @param {Object} self
     * @param {Object} data - selected item data
     */
    SelectPage.prototype.afterInit = function (self, data) {
        if (!data || ($.isArray(data) && data.length === 0))
            return;
        if (!$.isArray(data))
            data = [data];
        var p = self.option,
            css = self.css_class;

        var getText = function (row) {
            var text = row[p.showField];
            if (p.formatItem && $.isFunction(p.formatItem)) {
                try {
                    text = p.formatItem(row);
                } catch (e) {}
            }
            return text;
        };

        if (p.multiple) {
            self.prop.init_set = true;
            self.clearAll(self);
            $.each(data, function (i, row) {
                var item = {
                    text: getText(row),
                    value: row[p.keyField]
                };
                if (!self.isAlreadySelected(self, item))
                    self.addNewTag(self, item);
            });
            self.tagValuesSet(self);
            self.inputResize(self);
            self.prop.init_set = false;
        } else {
            var row = data[0];
            self.elem.combo_input.val(getText(row));
            self.elem.hidden.val(row[p.keyField]);
            self.prop.prev_value = getText(row);
            self.prop.selected_text = getText(row);
            if (p.selectOnly) {
                self.elem.combo_input.attr('title', self.message.select_ok).removeClass(css.select_ng).addClass(css.select_ok);
            }
            self.putClearButton();
        }
    };

    /**
     * Drop down button event bind
     */
    SelectPage.prototype.eDropdownButton = function () {
        var self = this;
        if (self.option.dropButton) {
            self.elem.button.mouseup(function (ev) {
                ev.stopPropagation();
                if (self.elem.result_area.is(':hidden') && !self.elem.combo_input.prop('disabled')) {
                    self.elem.combo_input.focus();
                } else
                    self.hideResults(self);
            });
        }
    };

    /**
     * Events bind
     */
    SelectPage.prototype.eInput = function () {
        var self = this,
            p = self.option,
            el = self.elem,
            msg = self.message;
        var showList = function () {
            self.prop.page_move = false;
            self.suggest(self);
            self.setCssFocusedInput(self);
        };
        el.combo_input.keyup(function (e) {
            self.processKey(self, e);
        }).keydown(function (e) {
            self.processControl(self, e);
        }).focus(function (e) {
            //When focus on input, show the result list
            if (el.result_area.is(':hidden')) {
                e.stopPropagation();
                self.prop.first_show = true;
                showList();
            }
        });
        el.container.on('click.SelectPage', 'div.' + self.css_class.clear_btn, function (e) {
            e.stopPropagation();
            if (!self.disabled(self)) {
                self.clearAll(self);
                self.elem.hidden.change();
                if (p.eClear && $.isFunction(p.eClear))
                    p.eClear(self);
            }
        });
        el.result_area.on('mousedown.SelectPage', function (e) {
            e.stopPropagation();
        });
        if (p.multiple) {
            if (p.multipleControlbar) {
                //Select all item of current page
                el.control.find('.sp_select_all').on('click.SelectPage', function (e) {
                    self.selectAllLine(self);
                }).hover(function () {
                    el.control_text.html(msg.select_all);
                }, function () {
                    el.control_text.html('');
                });
                //Cancel select all item of current page
                el.control.find('.sp_unselect_all').on('click.SelectPage', function (e) {
                    self.unSelectAllLine(self);
                }).hover(function () {
                    el.control_text.html(msg.unselect_all);
                }, function () {
                    el.control_text.html('');
                });
                //Clear all selected item
                el.control.find('.sp_clear_all').on('click.SelectPage', function (e) {
                    self.clearAll(self);
                }).hover(function () {
                    el.control_text.html(msg.clear_all);
                }, function () {
                    el.control_text.html('');
                });
            }
            el.element_box.on('click.SelectPage', function (e) {
                var srcEl = e.target || e.srcElement;
                if ($(srcEl).is('ul'))
                    el.combo_input.focus();
            });
            //Tag close
            el.element_box.on('click.SelectPage', 'span.tag_close', function () {
                var li = $(this).closest('li');
                self.removeTag(self, li);
                showList();
                if (p.eTagRemove && $.isFunction(p.eTagRemove))
                    p.eTagRemove(1, self);
            });
            self.inputResize(self);
        }
    };

    /**
     * Out of plugin area click event handler
     */
    SelectPage.prototype.eWhole = function () {
        var self = this,
            css = self.css_class;
        var cleanContent = function (obj) {
            obj.elem.combo_input.val('');
            if (!obj.option.multiple)
                obj.elem.hidden.val('');
            obj.prop.selected_text = '';
        };

        //Out of plugin area
        $(document.body).off('mousedown.selectPage').on('mousedown.selectPage', function (e) {
            var ele = e.target || e.srcElement;
            var sp = $(ele).closest('div.' + css.container);
            //Open status result list
            $('div.' + css.container + '.' + css.container_open).each(function () {
                if (this == sp[0])
                    return;
                var $this = $(this),
                    d = $this.find('input.' + css.input).data(SelectPage.dataKey);

                if (!d.elem.combo_input.val() && d.elem.hidden.val() && !d.option.multiple) {
                    d.prop.current_page = 1; //reset page to 1
                    cleanContent(d);
                    d.hideResults(d);
                    return true;
                }
                if (d.elem.results.find('li').not('.' + css.message_box).size()) {
                    if (d.option.autoFillResult) {
                        //have selected item, then hide result list
                        if (d.elem.hidden.val())
                            d.hideResults(d);
                        else if (d.elem.results.find('li.sp_over').size()) {
                            //no one selected and have highlight item, select the highlight item
                            d.selectCurrentLine(d, true);
                        } else if (d.option.autoSelectFirst) {
                            //no one selected, no one highlight, select the first item
                            d.nextLine(d);
                            d.selectCurrentLine(d, true);
                        } else
                            d.hideResults(d);
                    } else
                        d.hideResults(d);
                } else {
                    //when no one item match, clear search keywords
                    if (d.option.noResultClean)
                        cleanContent(d);
                    else {
                        if (!d.option.multiple)
                            d.elem.hidden.val('');
                    }
                    d.hideResults(d);
                }
            });
        });
    };

    /**
     * Result list event bind
     */
    SelectPage.prototype.eResultList = function () {
        var self = this,
            css = this.css_class;
        self.elem.results.children('li').hover(function () {
            if (self.prop.key_select) {
                self.prop.key_select = false;
                return;
            }
            if (!$(this).hasClass(css.selected) && !$(this).hasClass(css.message_box)) {
                $(this).addClass(css.select);
                self.setCssFocusedResults(self);
            }
        }, function () {
            $(this).removeClass(css.select);
        }).click(function (e) {
            if (self.prop.key_select) {
                self.prop.key_select = false;
                return;
            }
            e.preventDefault();
            e.stopPropagation();

            if (!$(this).hasClass(css.selected))
                self.selectCurrentLine(self, false);
        });
    };

    /**
     * Reposition result list when list beyond the visible area
     */
    SelectPage.prototype.eScroll = function () {
        var self = this,
            css = this.css_class;
        $(window).on('scroll.SelectPage', function (e) {
            $('div.' + css.container + '.' + css.container_open).each(function () {
                var $this = $(this),
                    d = $this.find('input.' + css.input).data(SelectPage.dataKey),
                    offset = d.elem.result_area.offset(),
                    screenScrollTop = $(window).scrollTop(),
                    docHeight = $(document).height(),
                    viewHeight = $(window).height(),
                    listHeight = d.elem.result_area.outerHeight(),
                    listBottom = offset.top + listHeight,
                    hasOverflow = docHeight > viewHeight,
                    down = d.elem.result_area.hasClass('shadowDown');
                if (hasOverflow) {
                    if (down) { //open down
                        if (listBottom > (viewHeight + screenScrollTop))
                            d.calcResultsSize(d);
                    } else { //open up
                        if (offset.top < screenScrollTop)
                            d.calcResultsSize(d);
                    }
                }
            });
        });
    };

    /**
     * Page bar button event bind
     */
    SelectPage.prototype.ePaging = function () {
        var self = this;
        if (!self.option.pagination)
            return;
        self.elem.navi.find('li.csFirstPage').off('click').on('click', function (ev) {
            //$(self.elem.combo_input).focus();
            ev.preventDefault();
            self.firstPage(self);
        });

        self.elem.navi.find('li.csPreviousPage').off('click').on('click', function (ev) {
            //$(self.elem.combo_input).focus();
            ev.preventDefault();
            self.prevPage(self);
        });

        self.elem.navi.find('li.csNextPage').off('click').on('click', function (ev) {
            //$(self.elem.combo_input).focus();
            ev.preventDefault();
            self.nextPage(self);
        });

        self.elem.navi.find('li.csLastPage').off('click').on('click', function (ev) {
            //$(self.elem.combo_input).focus();
            ev.preventDefault();
            self.lastPage(self);
        });
    };

    /**
     * Ajax request fail
     * @param {Object} self
     * @param {string} errorThrown
     */
    SelectPage.prototype.ajaxErrorNotify = function (self, errorThrown) {
        self.showMessage(self.message.ajax_error);
    };

    /**
     * Message box
     * @param {Object} self
     * @param msg {string} the text need to show
     */
    SelectPage.prototype.showMessage = function (self, msg) {
        if (!msg)
            return;
        var msgLi = '<li class="' + self.css_class.message_box + '"><i class="spfont sp-warning"></i> ' + msg + '</li>';
        self.elem.results.empty().append(msgLi).show();
        self.calcResultsSize(self);
        self.setOpenStatus(self, true);
        self.elem.control.hide();
        if (self.option.pagination)
            self.elem.navi.hide();
    };

    /**
     * @desc Scroll
     * @param {Object} self
     * @param {boolean} enforce
     */
    SelectPage.prototype.scrollWindow = function (self, enforce) {
        var current_result = self.getCurrentLine(self),
            target_top = (current_result && !enforce) ? current_result.offset().top : self.elem.container.offset().top,
            target_size;

        self.prop.size_li = self.elem.results.children('li:first').outerHeight();
        target_size = self.prop.size_li;

        var gap, client_height = $(window).height(),
            scroll_top = $(window).scrollTop(),
            scroll_bottom = scroll_top + client_height - target_size;
        if (current_result.length) {
            if (target_top < scroll_top || target_size > client_height) {
                //scroll to top
                gap = target_top - scroll_top;
            } else if (target_top > scroll_bottom) {
                //scroll down
                gap = target_top - scroll_bottom;
            } else
                return; //do not scroll
        } else if (target_top < scroll_top)
            gap = target_top - scroll_top;
        window.scrollBy(0, gap);
    };
    /**
     * change css class by status
     * @param self
     * @param status {boolean} true: open, false: close
     */
    SelectPage.prototype.setOpenStatus = function (self, status) {
        var el = self.elem,
            css = self.css_class;
        if (status) {
            el.container.addClass(css.container_open);
            el.result_area.addClass(css.result_open);
        } else {
            el.container.removeClass(css.container_open);
            el.result_area.removeClass(css.result_open);
        }
    };

    /**
     * input element in focus css class set
     * @param {Object} self
     */
    SelectPage.prototype.setCssFocusedInput = function (self) {
        //$(self.elem.results).addClass(self.css_class.re_off);
        //$(self.elem.combo_input).removeClass(self.css_class.input_off);
    };

    /**
     * set result list get focus and input element lost focus
     * @param {Object} self
     */
    SelectPage.prototype.setCssFocusedResults = function (self) {
        //$(self.elem.results).removeClass(self.css_class.re_off);
        //$(self.elem.combo_input).addClass(self.css_class.input_off);
    };

    /**
     * Quick search input keywords listener
     * @param {Object} self
     */
    SelectPage.prototype.checkValue = function (self) {
        var now_value = self.elem.combo_input.val();
        if (now_value != self.prop.prev_value) {
            self.prop.prev_value = now_value;
            self.prop.first_show = false;

            if (self.option.selectOnly)
                self.setButtonAttrDefault();
            if (!self.option.multiple && !now_value) {
                self.elem.combo_input.val('');
                self.elem.hidden.val('');
                self.elem.clear_btn.remove();
            }

            self.suggest(self);
        }
    };

    /**
     * Input handle（regular input）
     * @param {Object} self
     * @param {Object} e - event object
     */
    SelectPage.prototype.processKey = function (self, e) {
        if ($.inArray(e.keyCode, [37, 38, 39, 40, 27, 9, 13]) === -1) {
            if (e.keyCode != 16)
                self.setCssFocusedInput(self); // except Shift(16)
            self.inputResize(self);
            if ($.type(self.option.data) === 'string') {
                self.prop.last_input_time = e.timeStamp;
                setTimeout(function () {
                    if ((e.timeStamp - self.prop.last_input_time) === 0)
                        self.checkValue(self);
                }, self.option.inputDelay * 1000);
            } else {
                self.checkValue(self);
            }
        }
    }

    /**
     * Input handle（control key）
     * @param {Object} self
     * @param {Object} e - event object
     */
    SelectPage.prototype.processControl = function (self, e) {
        if (($.inArray(e.keyCode, [37, 38, 39, 40, 27, 9]) > -1 && self.elem.result_area.is(':visible')) ||
            ($.inArray(e.keyCode, [13, 9]) > -1 && self.getCurrentLine(self))) {
            e.preventDefault();
            e.stopPropagation();
            e.cancelBubble = true;
            e.returnValue = false;
            switch (e.keyCode) {
                case 37: // left
                    if (e.shiftKey)
                        self.firstPage(self);
                    else
                        self.prevPage(self);
                    break;
                case 38: // up
                    self.prop.key_select = true;
                    self.prevLine(self);
                    break;
                case 39: // right
                    if (e.shiftKey)
                        self.lastPage(self);
                    else
                        self.nextPage(self);
                    break;
                case 40: // down
                    if (self.elem.results.children('li').length) {
                        self.prop.key_select = true;
                        self.nextLine(self);
                    } else
                        self.suggest(self);
                    break;
                case 9: // tab
                    self.prop.key_paging = true;
                    self.selectCurrentLine(self, true);
                    //self.hideResults(self);
                    break;
                case 13: // return
                    self.selectCurrentLine(self, true);
                    break;
                case 27: //  escape
                    self.prop.key_paging = true;
                    self.hideResults(self);
                    break;
            }
        }
    };

    /**
     * Abort Ajax request
     * @param {Object} self
     */
    SelectPage.prototype.abortAjax = function (self) {
        if (self.prop.xhr) {
            self.prop.xhr.abort();
            self.prop.xhr = false;
        }
    };

    /**
     * Suggest result of search keywords
     * @param {Object} self
     */
    SelectPage.prototype.suggest = function (self) {
        var q_word, val = $.trim(self.elem.combo_input.val());
        if (self.option.multiple)
            q_word = val;
        else {
            if (val && val === self.prop.selected_text)
                q_word = '';
            else
                q_word = val;
        }
        q_word = q_word.split(/[\s　]+/);

        //Before show up result list callback
        if (self.option.eOpen && $.isFunction(self.option.eOpen))
            self.option.eOpen.call(self);

        self.abortAjax(self);
        //self.setLoading(self);
        var which_page_num = self.prop.current_page || 1;

        if (typeof self.option.data == 'object')
            self.searchForJson(self, q_word, which_page_num);
        else
            self.searchForDb(self, q_word, which_page_num);
    };

    /**
     * Loading
     * @param {Object} self
     */
    SelectPage.prototype.setLoading = function (self) {
        if (self.elem.results.html() === '') {
            //self.calcResultsSize(self);
            self.setOpenStatus(self, true);
        }
    };

    /**
     * Search for ajax
     * @param {Object} self
     * @param {Array} q_word - query keyword
     * @param {number} which_page_num - target page number
     */
    SelectPage.prototype.searchForDb = function (self, q_word, which_page_num) {
        var p = self.option;
        if (!p.eAjaxSuccess || !$.isFunction(p.eAjaxSuccess))
            self.hideResults(self);
        var _paramsFunc = p.params,
            _params = {},
            searchKey = p.searchField;
        //when have new query keyword, then reset page number to 1.
        if (q_word.length && q_word[0] && q_word[0] !== self.prop.prev_value)
            which_page_num = 1;
        var _orgParams = {
            q_word: q_word,
            pageNumber: which_page_num,
            pageSize: p.pageSize,
            andOr: p.andOr,
            orderBy: p.orderBy,
            searchTable: p.dbTable,
            showField: self.option.showField,
            keyField: self.option.keyField,
            searchField: self.option.searchField
        };
        _orgParams[searchKey] = q_word[0];
        if (_paramsFunc) {
            var result = $.isFunction(_paramsFunc) ? _paramsFunc() : _paramsFunc;
            if (result && $.isPlainObject(result)) {
                _params = $.extend({}, _orgParams, result);
            } else {
                _params = _orgParams;
            }
        } else
            _params = _orgParams;
        self.prop.xhr = $.ajax({
            dataType: 'json',
            url: p.data,
            type: 'POST',
            data: _params,
            success: function (returnData) {
                if (!returnData || !$.isPlainObject(returnData)) {
                    self.hideResults(self);
                    self.ajaxErrorNotify(self, errorThrown);
                    return;
                }
                var data = {},
                    json = {};
                try {
                    data = p.eAjaxSuccess(returnData);
                    json.originalResult = data.list;
                    json.cnt_whole = data.totalRow;
                } catch (e) {
                    self.showMessage(self, self.message.ajax_error);
                    return;
                }
                if (self.elem.navi) {
                    $(self.elem.navi).toggleClass("hide", json.cnt_whole <= json.originalResult.length);
                }

                json.candidate = [];
                json.keyField = [];
                if (typeof json.originalResult != 'object') {
                    self.prop.xhr = null;
                    self.notFoundSearch(self);
                    return;
                }
                json.cnt_page = json.originalResult.length;
                for (var i = 0; i < json.cnt_page; i++) {
                    for (var key in json.originalResult[i]) {
                        if (key == p.keyField) {
                            json.keyField.push(json.originalResult[i][key]);
                        }
                        if (key == p.showField) {
                            json.candidate.push(json.originalResult[i][key]);
                        }
                    }
                }
                self.prepareResults(self, json, q_word, which_page_num);
            },
            error: function (jqXHR, textStatus, errorThrown) {
                if (textStatus != 'abort') {
                    self.hideResults(self);
                    self.ajaxErrorNotify(self, errorThrown);
                }
            },
            complete: function () {
                self.prop.xhr = null;
            }
        });
    };

    /**
     * Search for json data source
     * @param {Object} self
     * @param {Array} q_word
     * @param {number} which_page_num
     */
    SelectPage.prototype.searchForJson = function (self, q_word, which_page_num) {
        var p = self.option,
            matched = [],
            esc_q = [],
            sorted = [],
            json = {},
            i = 0,
            arr_reg = [];

        //query keyword filter
        do {
            //'/\W/g'正则代表全部不是字母，数字，下划线，汉字的字符
            //将非法字符进行转义
            esc_q[i] = q_word[i].replace(/\W/g, '\\$&').toString();
            arr_reg[i] = new RegExp(esc_q[i], 'gi');
            i++;
        } while (i < q_word.length);

        // SELECT * FROM data WHERE field LIKE q_word;
        for (i = 0; i < p.data.length; i++) {
            var flag = false,
                row = p.data[i],
                itemText;
            for (var j = 0; j < arr_reg.length; j++) {
                itemText = row[p.searchField];
                if (p.formatItem && $.isFunction(p.formatItem))
                    itemText = p.formatItem(row);
                if (itemText.match(arr_reg[j])) {
                    flag = true;
                    if (p.andOr == 'OR')
                        break;
                } else {
                    flag = false;
                    if (p.andOr == 'AND')
                        break;
                }
            }
            if (flag)
                matched.push(row);
        }

        // (CASE WHEN ...) then く order some column
        var reg1 = new RegExp('^' + esc_q[0] + '$', 'gi'),
            reg2 = new RegExp('^' + esc_q[0], 'gi'),
            matched1 = [],
            matched2 = [],
            matched3 = [];
        for (i = 0; i < matched.length; i++) {
            var orderField = p.orderBy[0][0];
            var orderValue = String(matched[i][orderField]);
            if (orderValue.match(reg1)) {
                matched1.push(matched[i]);
            } else if (orderValue.match(reg2)) {
                matched2.push(matched[i]);
            } else {
                matched3.push(matched[i]);
            }
        }

        if (p.orderBy[0][1].match(/^asc$/i)) {
            matched1 = self.sortAsc(self, matched1);
            matched2 = self.sortAsc(self, matched2);
            matched3 = self.sortAsc(self, matched3);
        } else {
            matched1 = self.sortDesc(self, matched1);
            matched2 = self.sortDesc(self, matched2);
            matched3 = self.sortDesc(self, matched3);
        }
        sorted = sorted.concat(matched1).concat(matched2).concat(matched3);

        /*
         if (sorted.length === undefined || sorted.length === 0 ) {
         self.notFoundSearch(self);
         return;
         }
         */
        json.cnt_whole = sorted.length;
        //page_move used to distinguish between init plugin or page moving
        if (!self.prop.page_move) {
            //only single mode can be used page number relocation
            if (!p.multiple) {
                //get selected item belong page number
                var currentValue = self.elem.hidden.val();
                if ($.type(currentValue) !== 'undefined' && $.trim(currentValue) !== '') {
                    var index = 0;
                    $.each(sorted, function (i, row) {
                        if (row[p.keyField] == currentValue) {
                            index = i + 1;
                            return false;
                        }
                    });
                    which_page_num = Math.ceil(index / p.pageSize);
                    if (which_page_num < 1)
                        which_page_num = 1;
                    self.prop.current_page = which_page_num;
                }
            }
        } else {
            //set page number to 1 when result number less then page size
            if (sorted.length <= ((which_page_num - 1) * p.pageSize)) {
                which_page_num = 1;
                self.prop.current_page = 1;
            }
        }

        //LIMIT xx OFFSET xx
        var start = (which_page_num - 1) * p.pageSize,
            end = start + p.pageSize;
        //save original data
        json.originalResult = [];
        //after data filter handle
        for (i = start; i < end; i++) {
            if (sorted[i] === undefined)
                break;
            json.originalResult.push(sorted[i]);
            for (var key in sorted[i]) {
                if (key == p.keyField) {
                    if (json.keyField === undefined)
                        json.keyField = [];
                    json.keyField.push(sorted[i][key]);
                }
                if (key == p.showField) {
                    if (json.candidate === undefined)
                        json.candidate = [];
                    json.candidate.push(sorted[i][key]);
                }
            }
        }

        if (json.candidate === undefined)
            json.candidate = [];
        json.cnt_page = json.candidate.length;
        self.prepareResults(self, json, q_word, which_page_num);
    };

    /**
     * Set order asc
     * @param {Object} self
     * @param {Array} arr - result array
     */
    SelectPage.prototype.sortAsc = function (self, arr) {
        arr.sort(function (a, b) {
            var valA = a[self.option.orderBy[0][0]],
                valB = b[self.option.orderBy[0][0]];
            return $.type(valA) === 'number' ? valA - valB : String(valA).localeCompare(String(valB));
        });
        return arr;
    };

    /**
     * Set order desc
     * @param {Object} self
     * @param {Array} arr - result array
     */
    SelectPage.prototype.sortDesc = function (self, arr) {
        arr.sort(function (a, b) {
            var valA = a[self.option.orderBy[0][0]],
                valB = b[self.option.orderBy[0][0]];
            return $.type(valA) === 'number' ? valB - valA : String(valB).localeCompare(String(valA));
        });
        return arr;
    };

    /**
     * Not result found handle
     * @param {Object} self
     */
    SelectPage.prototype.notFoundSearch = function (self) {
        self.elem.results.empty();
        self.calcResultsSize(self);
        self.setOpenStatus(self, true);
        self.setCssFocusedInput(self);
    };

    /**
     * Prepare data to show
     * @param {Object} self
     * @param {Object} json - data result
     * @param {Array} q_word - query keyword
     * @param {number} which_page_num - target page number
     */
    SelectPage.prototype.prepareResults = function (self, json, q_word, which_page_num) {
        if (self.option.pagination)
            self.setNavi(self, json.cnt_whole, json.cnt_page, which_page_num);

        if (!json.keyField)
            json.keyField = false;

        if (self.option.selectOnly && json.candidate.length === 1 && json.candidate[0] == q_word[0]) {
            self.elem.hidden.val(json.keyField[0]);
            this.setButtonAttrDefault();
        }
        var is_query = false;
        if (q_word && q_word.length && q_word[0])
            is_query = true;
        self.displayResults(self, json, is_query);
    };

    /**
     * Build page bar
     * @param {Object} self
     * @param {number} cnt_whole - total record count
     * @param {number} cnt_page
     * @param {number} page_num - current page number
     */
    SelectPage.prototype.setNavi = function (self, cnt_whole, cnt_page, page_num) {
        var msg = self.message;
        /**
         * build pagination bar
         */
        var buildPageNav = function (self, pagebar, page_num, last_page) {
            var updatePageInfo = function () {
                var pageInfo = msg.page_info;
                return pageInfo.replace(self.template.page.current, page_num).replace(self.template.page.total, last_page);
            };
            if (pagebar.find('li').size() === 0) {
                pagebar.hide().empty();
                var iconFist = 'spfont sp-first',
                    iconPrev = 'spfont sp-previous',
                    iconNext = 'spfont sp-next',
                    iconLast = 'spfont sp-last';

                pagebar.append('<li class="csFirstPage" title="' + msg.first_title + '" ><a href="javascript:void(0);"> <i class="' + iconFist + '"></i> </a></li>');
                pagebar.append('<li class="csPreviousPage" title="' + msg.prev_title + '" ><a href="javascript:void(0);"><i class="' + iconPrev + '"></i></a></li>');
                //pagination information
                pagebar.append('<li class="pageInfoBox"><a href="javascript:void(0);"> ' + updatePageInfo() + ' </a></li>');

                pagebar.append('<li class="csNextPage" title="' + msg.next_title + '" ><a href="javascript:void(0);"><i class="' + iconNext + '"></i></a></li>');
                pagebar.append('<li class="csLastPage" title="' + msg.last_title + '" ><a href="javascript:void(0);"> <i class="' + iconLast + '"></i> </a></li>');
                pagebar.show();
            } else {
                pagebar.find('li.pageInfoBox a').html(updatePageInfo());
            }
        };

        var pagebar = self.elem.navi.find('ul'),
            last_page = Math.ceil(cnt_whole / self.option.pageSize); //calculate total page
        if (last_page === 0)
            page_num = 0;
        else {
            if (last_page < page_num)
                page_num = last_page;
            else if (page_num === 0)
                page_num = 1;
        }
        self.prop.current_page = page_num; //update current page number
        self.prop.max_page = last_page; //update page count
        buildPageNav(self, pagebar, page_num, last_page);

        //update paging status
        var dClass = 'disabled',
            first = pagebar.find('li.csFirstPage'),
            previous = pagebar.find('li.csPreviousPage'),
            next = pagebar.find('li.csNextPage'),
            last = pagebar.find('li.csLastPage');
        //first and previous
        if (page_num === 1 || page_num === 0) {
            if (!first.hasClass(dClass))
                first.addClass(dClass);
            if (!previous.hasClass(dClass))
                previous.addClass(dClass);
        } else {
            if (first.hasClass(dClass))
                first.removeClass(dClass);
            if (previous.hasClass(dClass))
                previous.removeClass(dClass);
        }
        //next and last
        if (page_num === last_page || last_page === 0) {
            if (!next.hasClass(dClass))
                next.addClass(dClass);
            if (!last.hasClass(dClass))
                last.addClass(dClass);
        } else {
            if (next.hasClass(dClass))
                next.removeClass(dClass);
            if (last.hasClass(dClass))
                last.removeClass(dClass);
        }

        if (last_page > 1)
            self.ePaging(); //pagination event bind
    };

    /**
     * Render result list
     * @param {Object} self
     * @param {Object} json - result data
     * @param {boolean} is_query - used to different from search to open and just click to open
     */
    SelectPage.prototype.displayResults = function (self, json, is_query) {
        var p = self.option,
            el = self.elem;
        el.results.hide().empty();
        if (p.multiple && $.type(p.maxSelectLimit) === 'number' && p.maxSelectLimit > 0) {
            var selectedSize = el.element_box.find('li.selected_tag').size();
            if (selectedSize > 0 && selectedSize >= p.maxSelectLimit) {
                var msg = self.message.max_selected;
                self.showMessage(self, msg.replace(self.template.msg.maxSelectLimit, p.maxSelectLimit));
                return;
            }
        }

        if (json.candidate.length) {
            var arr_candidate = json.candidate,
                arr_primary_key = json.keyField,
                keystr = el.hidden.val(),
                keyArr = keystr ? keystr.split(',') : new Array(),
                itemText = '';
            for (var i = 0; i < arr_candidate.length; i++) {
                if (p.formatItem && $.isFunction(p.formatItem)) {
                    try {
                        itemText = p.formatItem(json.originalResult[i]);
                    } catch (e) {
                        console.error('formatItem内容格式化函数内容设置不正确！');
                        itemText = arr_candidate[i];
                    }
                } else
                    itemText = arr_candidate[i];
                var list = $('<li>').html(itemText).attr({
                    pkey: arr_primary_key[i]
                });
                if (!p.formatItem)
                    list.attr('title', itemText);

                //Set selected item highlight
                if ($.inArray(arr_primary_key[i].toString(), keyArr) !== -1) {
                    list.addClass(self.css_class.selected);
                }
                //cache item data
                list.data('dataObj', json.originalResult[i]);
                el.results.append(list);
            }
        } else {
            var li = '<li class="' + self.css_class.message_box + '"><i class="spfont sp-warning"></i> ' +
                self.message.not_found + '</li>';
            el.results.append(li);
        }
        el.results.show();

        if (p.multiple && p.multipleControlbar)
            el.control.show();
        if (p.pagination)
            el.navi.show();
        self.calcResultsSize(self);
        self.setOpenStatus(self, true);

        //Result item event bind
        self.eResultList();
        //scrolling listen
        self.eScroll();
        //auto highlight first item in search, have result and set autoSelectFirst to true situation
        if (is_query && json.candidate.length && p.autoSelectFirst)
            self.nextLine(self);
    };

    /**
     * Calculate result list size and position
     * @param {Object} self
     */
    SelectPage.prototype.calcResultsSize = function (self) {
        var p = self.option,
            el = self.elem;
        var rePosition = function () {
            if (el.container.css('position') === 'static') {
                // position: static
                var offset = el.combo_input.offset();
                el.result_area.css({
                    top: offset.top + el.combo_input.outerHeight() + 'px',
                    left: offset.left + 'px'
                });
            } else {
                if (!p.pagination) {
                    var itemHeight = el.results.find('li:first').outerHeight(true),
                        listHeight = itemHeight * p.listSize;
                    el.results.css({
                        'max-height': listHeight,
                        'overflow-y': 'auto'
                    });
                }

                //handle result list show up side(left, right, up or down)
                var docWidth = $(document).width(),
                    docHeight = $(document).height(), //the document full height
                    viewHeight = $(window).height(), //browser visible area height
                    offset = el.container.offset(),
                    screenScrollTop = $(window).scrollTop(),
                    listWidth = el.result_area.outerWidth(),
                    //result list height
                    listHeight = el.result_area.outerHeight(),
                    //default left used input element left
                    defaultLeft = offset.left, //p.multiple ? -1 : 0;
                    //input element height
                    inputHeight = el.container.outerHeight(),
                    left = (offset.left + listWidth) > docWidth ?
                    defaultLeft - (listWidth - el.container.outerWidth()) :
                    defaultLeft,
                    //the actual top coordinate of input element(outer div)
                    screenTop = offset.top, //$(el.container).scrollTop();//offset.top - screenScrollTop;
                    top = 0,
                    dist = 5, //set distance between input element and result list
                    //the actual top coordinate of result list
                    listBottom = screenTop + inputHeight + listHeight + dist,
                    hasOverflow = docHeight > viewHeight;

                if ((screenTop - screenScrollTop - dist > listHeight) &&
                    (hasOverflow && listBottom > (viewHeight + screenScrollTop)) ||
                    (!hasOverflow && listBottom > viewHeight)) {
                    //open up
                    top = offset.top - listHeight - dist;
                    el.result_area.removeClass('shadowUp shadowDown').addClass('shadowUp');
                } else {
                    //open down
                    top = offset.top + (p.multiple ? el.container.outerHeight() : inputHeight);
                    el.result_area.removeClass('shadowUp shadowDown').addClass('shadowDown');
                    top += dist;
                }
                return {
                    top: top + 'px',
                    left: left + 'px'
                };
            }
        };
        if (el.result_area.is(':visible')) {
            el.result_area.css(rePosition());
        } else {
            var pss = rePosition();
            el.result_area.css(pss).show(1, function () {
                var repss = rePosition();
                if (pss.top !== repss.top || pss.left !== repss.left)
                    el.result_area.css(repss);
            });
        }
    };

    /**
     * hide result list
     * @param {Object} self
     */
    SelectPage.prototype.hideResults = function (self) {
        if (self.prop.key_paging) {
            self.scrollWindow(self, true);
            self.prop.key_paging = false;
        }
        self.setCssFocusedInput(self);

        if (self.option.autoFillResult) {
            //self.selectCurrentLine(self, true);
        }

        self.elem.results.empty();
        self.elem.result_area.hide();
        self.setOpenStatus(self, false);
        //unbind window scroll listen
        $(window).off('scroll.SelectPage');

        self.abortAjax(self);
        self.setButtonAttrDefault();
    };

    /**
     * set plugin to disabled / enabled
     * @param self
     * @param disabled
     */
    SelectPage.prototype.disabled = function (self, disabled) {
        var p = self.option,
            el = self.elem;
        if ($.type(disabled) === 'undefined')
            return el.combo_input.prop('disabled');
        if ($.type(disabled) === 'boolean') {
            el.combo_input.prop('disabled', disabled);
            if (disabled)
                el.container.addClass(self.css_class.disabled);
            else
                el.container.removeClass(self.css_class.disabled);
        }
    };

    /**
     * Go fist page
     * @param {Object} self
     */
    SelectPage.prototype.firstPage = function (self) {
        if (self.prop.current_page > 1) {
            self.prop.current_page = 1;
            self.prop.page_move = true;
            self.suggest(self);
        }
    };

    /**
     * Go previous page
     * @param {Object} self
     */
    SelectPage.prototype.prevPage = function (self) {
        if (self.prop.current_page > 1) {
            self.prop.current_page--;
            self.prop.page_move = true;
            self.suggest(self);
        }
    };

    /**
     * Go next page
     * @param {Object} self
     */
    SelectPage.prototype.nextPage = function (self) {
        if (self.prop.current_page < self.prop.max_page) {
            self.prop.current_page++;
            self.prop.page_move = true;
            self.suggest(self);
        }
    };

    /**
     * Go last page
     * @param {Object} self
     */
    SelectPage.prototype.lastPage = function (self) {
        if (self.prop.current_page < self.prop.max_page) {
            self.prop.current_page = self.prop.max_page;
            self.prop.page_move = true;
            self.suggest(self);
        }
    };
    /**
     * do something after select/unSelect action
     * @param {Object} self
     */
    SelectPage.prototype.afterAction = function (self) {
        self.inputResize(self);
        self.elem.combo_input.change();
        self.setCssFocusedInput(self);
        if (self.prop.init_set)
            return;
        if (self.option.multiple) {
            if (self.option.selectToCloseList) {
                self.hideResults(self);
                self.elem.combo_input.blur();
            } else {
                self.suggest(self);
                self.elem.combo_input.focus();
            }
        } else {
            self.hideResults(self);
            self.elem.combo_input.blur();
        }
    };

    /**
     * Select current list item
     * @param {Object} self
     * @param {boolean} is_enter_key
     */
    SelectPage.prototype.selectCurrentLine = function (self, is_enter_key) {
        self.scrollWindow(self, true);

        var p = self.option,
            current = self.getCurrentLine(self);
        if (current) {
            if (!p.multiple) {
                self.elem.combo_input.val(current.text());
                self.elem.hidden.val(current.attr('pkey'));
            } else {
                //build tags in multiple selection mode
                self.elem.combo_input.val('');
                var item = {
                    text: current.text(),
                    value: current.attr('pkey')
                };
                if (!self.isAlreadySelected(self, item)) {
                    self.addNewTag(self, item);
                    self.tagValuesSet(self);
                }
            }

            if (p.selectOnly)
                self.setButtonAttrDefault();

            //Select item callback
            if (p.eSelect && $.isFunction(p.eSelect))
                p.eSelect(current.data('dataObj'), self);

            self.prop.prev_value = self.elem.combo_input.val();
            self.prop.selected_text = self.elem.combo_input.val();

            self.putClearButton();
        }
        self.afterAction(self);
    };
    /**
     * Show clear button when item selected in single selection mode
     */
    SelectPage.prototype.putClearButton = function () {
        if (!this.option.multiple && !this.elem.combo_input.prop('disabled'))
            this.elem.container.append(this.elem.clear_btn);
    };
    /**
     * Select all list item
     * @param {Object} self
     */
    SelectPage.prototype.selectAllLine = function (self) {
        var p = self.option,
            jsonarr = new Array();
        self.elem.results.find('li').each(function (i, row) {
            var $row = $(row);
            var item = {
                text: $row.text(),
                value: $row.attr('pkey')
            };
            if (!self.isAlreadySelected(self, item)) {
                self.addNewTag(self, item);
                self.tagValuesSet(self);
            }
            jsonarr.push($row.data('dataObj'));
            //limited max selected items
            if ($.type(p.maxSelectLimit) === 'number' &&
                p.maxSelectLimit > 0 &&
                p.maxSelectLimit === self.elem.element_box.find('li.selected_tag').size()) {
                return false;
            }
        });
        if (p.eSelect && $.isFunction(p.eSelect))
            p.eSelect(jsonarr, self);
        self.afterAction(self);
    };
    /**
     * Cancel select all item in current page
     * @param {Object} self
     */
    SelectPage.prototype.unSelectAllLine = function (self) {
        var p = self.option,
            size = self.elem.results.find('li').size();
        self.elem.results.find('li').each(function (i, row) {
            var key = $(row).attr('pkey');
            var tag = self.elem.element_box.find('li.selected_tag[itemvalue="' + key + '"]');
            self.removeTag(self, tag);
        });
        self.afterAction(self);
        if (p.eTagRemove && $.isFunction(p.eTagRemove))
            p.eTagRemove(size, self);
    };
    /**
     * Clear all selected items
     * @param {Object} self
     */
    SelectPage.prototype.clearAll = function (self) {
        var p = self.option,
            size = 0;
        if (p.multiple) {
            size = self.elem.element_box.find('li.selected_tag').size();
            self.elem.element_box.find('li.selected_tag').remove();
        }
        self.reset(self);
        self.afterAction(self);

        if (!p.multiple)
            self.elem.clear_btn.remove();
        if (p.multiple) {
            if (p.eTagRemove && $.isFunction(p.eTagRemove))
                p.eTagRemove(size, self);
        }
    };

    /**
     * reset
     */
    SelectPage.prototype.reset = function (self) {
        self.elem.combo_input.val('');
        self.elem.hidden.val('');
        self.prop.prev_value = '';
        self.prop.selected_text = '';
        self.prop.current_page = 1;
    };

    /**
     * Get current highlight item
     * @param {Object} self
     */
    SelectPage.prototype.getCurrentLine = function (self) {
        if (self.elem.result_area.is(':hidden'))
            return false;
        var obj = self.elem.results.find('li.' + self.css_class.select);
        if (obj.size())
            return obj;
        else
            return false;
    };

    /**
     * Check the result item is already selected or not
     * @param {Object} self
     * @param {Object} item - item info
     */
    SelectPage.prototype.isAlreadySelected = function (self, item) {
        var isExist = false;
        if (item.value) {
            var keys = self.elem.hidden.val();
            if (keys) {
                var karr = keys.split(',');
                if (karr && karr.length && $.inArray(item.value, karr) != -1)
                    isExist = true;
            }
        }
        return isExist;
    };

    /**
     * Add a new tag in multiple selection mode
     * @param {Object} self
     * @param {Object} item
     */
    SelectPage.prototype.addNewTag = function (self, item) {
        if (!self.option.multiple || !item)
            return;
        var tmp = self.template.tag.content,
            tag;
        tmp = tmp.replace(self.template.tag.textKey, item.text);
        tmp = tmp.replace(self.template.tag.valueKey, item.value);
        tag = $(tmp);
        if (self.elem.combo_input.prop('disabled'))
            tag.find('span.tag_close').hide();
        self.elem.combo_input.closest('li').before(tag);
    };
    /**
     * Remove a tag in multiple selection mode
     * @param {Object} self
     * @param {Object} item
     */
    SelectPage.prototype.removeTag = function (self, item) {
        var key = $(item).attr('itemvalue');
        var keys = self.elem.hidden.val();
        if ($.type(key) != 'undefined' && keys) {
            var keyarr = keys.split(','),
                index = $.inArray(key.toString(), keyarr);
            if (index != -1) {
                keyarr.splice(index, 1);
                self.elem.hidden.val(keyarr.toString());
            }
        }
        $(item).remove();
        self.afterAction(self);
    };

    /**
     * Selected item value(keyField) put in to hidden element
     * @param {Object} self
     */
    SelectPage.prototype.tagValuesSet = function (self) {
        if (!self.option.multiple)
            return;
        var tags = self.elem.element_box.find('li.selected_tag');
        if (tags && tags.size()) {
            var result = new Array();
            $.each(tags, function (i, li) {
                var v = $(li).attr('itemvalue');
                if ($.type(v) !== 'undefined')
                    result.push(v);
            });
            if (result.length) {
                self.elem.hidden.val(result.join(','));
            }
        }
    };

    /**
     * auto resize input element width in multiple select mode
     * @param {Object} self
     */
    SelectPage.prototype.inputResize = function (self) {
        if (!self.option.multiple)
            return;
        var width = '',
            inputLi = self.elem.combo_input.closest('li');
        var setDefaultSize = function (self, inputLi) {
            inputLi.removeClass('full_width');
            var minimumWidth = self.elem.combo_input.val().length + 1,
                width = (minimumWidth * 0.75) + 'em';
            self.elem.combo_input.css('width', width).removeAttr('placeholder');
        };
        if (self.elem.element_box.find('li.selected_tag').size() === 0) {
            if (self.elem.combo_input.attr('placeholder_bak')) {
                if (!inputLi.hasClass('full_width'))
                    inputLi.addClass('full_width');
                self.elem.combo_input.attr('placeholder', self.elem.combo_input.attr('placeholder_bak')).removeAttr('style');
            } else
                setDefaultSize(self, inputLi);
        } else
            setDefaultSize(self, inputLi);
    };

    /**
     * Move to next line
     * @param {Object} self
     */
    SelectPage.prototype.nextLine = function (self) {
        var obj = self.getCurrentLine(self),
            idx;
        if (!obj)
            idx = -1;
        else {
            idx = self.elem.results.children('li').index(obj);
            obj.removeClass(self.css_class.select);
        }
        idx++;
        if (idx < self.elem.results.children('li').length) {
            var next = self.elem.results.children('li').eq(idx);
            next.addClass(self.css_class.select);
            self.setCssFocusedResults(self);
        } else
            self.setCssFocusedInput(self);
        self.scrollWindow(self, false);
    };

    /**
     * Move to previous line
     * @param {Object} self
     */
    SelectPage.prototype.prevLine = function (self) {
        var obj = self.getCurrentLine(self),
            idx;
        if (!obj)
            idx = self.elem.results.children('li').length;
        else {
            idx = self.elem.results.children('li').index(obj);
            obj.removeClass(self.css_class.select);
        }
        idx--;
        if (idx > -1) {
            var prev = self.elem.results.children('li').eq(idx);
            prev.addClass(self.css_class.select);
            self.setCssFocusedResults(self);
        } else
            self.setCssFocusedInput(self);
        self.scrollWindow(self, false);
    };


    /**
     * SelectPage plugin definition
     * @global
     * @param option {Object} init plugin option
     */
    function Plugin(option) {
        return this.each(function () {
            var $this = $(this),
                data = $this.data(SelectPage.dataKey),
                params = $.extend({}, defaults, $this.data(), data && data.option, typeof option === 'object' && option);
            if (!data)
                $this.data(SelectPage.dataKey, (data = new SelectPage(this, params)));
        });
    }

    /**
     * Get plugin object
     * @param {object} obj 
     * @returns 
     */
    function getPlugin(obj) {
        return $(obj).closest('div.sp_container').find('input.sp_input');
    }

    /**
     * Clear all selected item
     */
    function ClearSelected() {
        return this.each(function () {
            var $this = getPlugin(this),
                data = $this.data(SelectPage.dataKey);
            if (data) {
                data.prop.init_set = true;
                data.clearAll(data);
                data.prop.init_set = false;
            }
        });
    }

    /**
     * Refresh result list
     * use case:
     * 1.use $(obj).val('xxx') to modify selectpage selected item key
     * 2.refresh selected item show content/tag text
     */
    function SelectedRefresh() {
        return this.each(function () {
            var $this = getPlugin(this),
                data = $this.data(SelectPage.dataKey);
            if (data && data.elem.hidden.val())
                data.setInitRecord(true);
        });
    }

    /**
     * Modify plugin datasource, only work on json datasource mode
     * @param {array} data - new datasource
     * @example
     * [{name:'aa',sex:1},{name:'bb',sex:0},{...}]
     */
    function ModifyDataSource(data) {
        return this.each(function () {
            if (data && $.isArray(data)) {
                var $this = getPlugin(this),
                    plugin = $this.data(SelectPage.dataKey);
                if (plugin) {
                    plugin.clearAll(plugin);
                    plugin.option.data = data;
                }
            }
        });
    }

    /**
     * Get plugin disabled status or Modify plugin disabled status
     * @param disabled {boolean} set disabled status
     */
    function PluginDisabled(disabled) {
        var status = false;
        this.each(function () {
            var $this = getPlugin(this),
                plugin = $this.data(SelectPage.dataKey);
            if (plugin) {
                if ($.type(disabled) !== 'undefined')
                    plugin.disabled(plugin, disabled);
                else
                    status = plugin.disabled(plugin);
            }
        });
        return status;
    }

    /**
     * Get selected item text
     * @returns {string}
     */
    function GetInputText() {
        var str = '';
        this.each(function () {
            var $this = getPlugin(this),
                data = $this.data(SelectPage.dataKey);
            if (data) {
                if (data.option.multiple) {
                    var tags = [];
                    data.elem.element_box.find('li.selected_tag').each(function (i, tag) {
                        tags.push($(tag).text());
                    });
                    str += tags.toString();
                } else {
                    str += data.elem.combo_input.val();
                }
            }
        });
        return str;
    }

    var old = $.fn.selectPage;

    $.fn.selectPage = Plugin;
    $.fn.selectPage.Constructor = SelectPage;
    $.fn.selectPageClear = ClearSelected;
    $.fn.selectPageRefresh = SelectedRefresh;
    $.fn.selectPageData = ModifyDataSource;
    $.fn.selectPageDisabled = PluginDisabled;
    $.fn.selectPageText = GetInputText;

    // SelectPage no conflict
    // =================
    $.fn.selectPage.noConflict = function () {
        $.fn.selectPage = old;
        return this;
    };
})(window.jQuery);

define("selectpage", function () {});

/**
 * jQuery Editable Select
 * Indri Muska <indrimuska@gmail.com>
 *
 * Source on GitHub @ https://github.com/indrimuska/jquery-editable-select
 */

+
(function ($) {
    // jQuery Editable Select
    EditableSelect = function (select, options) {
        var that = this;

        this.options = options;
        this.$select = $(select);
        this.$input = $('<input type="text" autocomplete="off">');
        this.$list = $('<ul class="es-list">');
        this.utility = new EditableSelectUtility(this);

        if (['focus', 'manual'].indexOf(this.options.trigger) < 0) this.options.trigger = 'focus';
        if (['default', 'fade', 'slide'].indexOf(this.options.effects) < 0) this.options.effects = 'default';
        if (isNaN(this.options.duration) && ['fast', 'slow'].indexOf(this.options.duration) < 0) this.options.duration = 'fast';

        // create text input
        this.$select.replaceWith(this.$input);
        this.$list.appendTo(this.options.appendTo || this.$input.parent());

        // initalization
        this.utility.initialize();
        this.utility.initializeList();
        this.utility.initializeInput();
        this.utility.trigger('created');
    }
    EditableSelect.DEFAULTS = {
        filter: true,
        effects: 'default',
        duration: 'fast',
        trigger: 'focus'
    };
    EditableSelect.prototype.filter = function () {
        var hiddens = 0;
        var search = this.$input.val().toLowerCase().trim();

        this.$list.find('li').addClass('es-visible').show();
        if (this.options.filter) {
            hiddens = this.$list.find('li').filter(function (i, li) {
                return $(li).text().toLowerCase().indexOf(search) < 0;
            }).hide().removeClass('es-visible').length;
            if (this.$list.find('li').length == hiddens) this.hide();
        }
    };
    EditableSelect.prototype.show = function () {
        this.$list.css({
            top: this.$input.position().top + this.$input.outerHeight() - 1,
            left: this.$input.position().left,
            width: this.$input.outerWidth()
        });

        if (!this.$list.is(':visible') && this.$list.find('li.es-visible').length > 0) {
            var fns = {
                default: 'show',
                fade: 'fadeIn',
                slide: 'slideDown'
            };
            var fn = fns[this.options.effects];

            this.utility.trigger('show');
            this.$input.addClass('open');
            this.$list[fn](this.options.duration, $.proxy(this.utility.trigger, this.utility, 'shown'));
        }
    };
    EditableSelect.prototype.hide = function () {
        var fns = {
            default: 'hide',
            fade: 'fadeOut',
            slide: 'slideUp'
        };
        var fn = fns[this.options.effects];

        this.utility.trigger('hide');
        this.$input.removeClass('open');
        this.$list[fn](this.options.duration, $.proxy(this.utility.trigger, this.utility, 'hidden'));
    };
    EditableSelect.prototype.select = function ($li) {
        if (!this.$list.has($li) || !$li.is('li.es-visible:not([disabled])')) return;
        this.$input.val($li.text());
        if (this.options.filter) this.hide();
        this.filter();
        this.utility.trigger('select', $li);
    };
    EditableSelect.prototype.add = function (text, index, attrs, data) {
        var $li = $('<li>').html(text);
        var $option = $('<option>').text(text);
        var last = this.$list.find('li').length;

        if (isNaN(index)) index = last;
        else index = Math.min(Math.max(0, index), last);
        if (index == 0) {
            this.$list.prepend($li);
            this.$select.prepend($option);
        } else {
            this.$list.find('li').eq(index - 1).after($li);
            this.$select.find('option').eq(index - 1).after($option);
        }
        this.utility.setAttributes($li, attrs, data);
        this.utility.setAttributes($option, attrs, data);
        this.filter();
    };
    EditableSelect.prototype.remove = function (index) {
        var last = this.$list.find('li').length;

        if (isNaN(index)) index = last;
        else index = Math.min(Math.max(0, index), last - 1);
        this.$list.find('li').eq(index).remove();
        this.$select.find('option').eq(index).remove();
        this.filter();
    };
    EditableSelect.prototype.clear = function () {
        this.$list.find('li').remove();
        this.$select.find('option').remove();
        this.filter();
    };
    EditableSelect.prototype.destroy = function () {
        this.$list.off('mousemove mousedown mouseup');
        this.$input.off('focus blur input keydown');
        this.$input.replaceWith(this.$select);
        this.$list.remove();
        this.$select.removeData('editable-select');
    };

    // Utility
    EditableSelectUtility = function (es) {
        this.es = es;
    }
    EditableSelectUtility.prototype.initialize = function () {
        var that = this;
        that.setAttributes(that.es.$input, that.es.$select[0].attributes, that.es.$select.data());
        that.es.$input.addClass('es-input').data('editable-select', that.es);
        that.es.$select.find('option').each(function (i, option) {
            var $option = $(option).remove();
            that.es.add($option.text(), i, option.attributes, $option.data());
            if ($option.attr('selected')) that.es.$input.val($option.text());
        });
        that.es.filter();
    };
    EditableSelectUtility.prototype.initializeList = function () {
        var that = this;
        that.es.$list
            .on('mousemove', 'li:not([disabled])', function () {
                that.es.$list.find('.selected').removeClass('selected');
                $(this).addClass('selected');
            })
            .on('mousedown', 'li', function (e) {
                if ($(this).is('[disabled]')) e.preventDefault();
                else that.es.select($(this));
            })
            .on('mouseup', function () {
                that.es.$list.find('li.selected').removeClass('selected');
            });
    };
    EditableSelectUtility.prototype.initializeInput = function () {
        var that = this;
        switch (this.es.options.trigger) {
            default:
            case 'focus':
                that.es.$input
                    .on('focus', $.proxy(that.es.show, that.es))
                    .on('blur', $.proxy(that.es.hide, that.es));
                break;
            case 'manual':
                break;
        }
        that.es.$input.on('input keydown', function (e) {
            switch (e.keyCode) {
                case 38: // Up
                    var visibles = that.es.$list.find('li.es-visible:not([disabled])');
                    var selectedIndex = visibles.index(visibles.filter('li.selected'));
                    that.highlight(selectedIndex - 1);
                    e.preventDefault();
                    break;
                case 40: // Down
                    var visibles = that.es.$list.find('li.es-visible:not([disabled])');
                    var selectedIndex = visibles.index(visibles.filter('li.selected'));
                    that.highlight(selectedIndex + 1);
                    e.preventDefault();
                    break;
                case 13: // Enter
                    if (that.es.$list.is(':visible')) {
                        that.es.select(that.es.$list.find('li.selected'));
                        e.preventDefault();
                    }
                    break;
                case 9: // Tab
                case 27: // Esc
                    that.es.hide();
                    break;
                default:
                    that.es.filter();
                    that.highlight(0);
                    break;
            }
        });
    };
    EditableSelectUtility.prototype.highlight = function (index) {
        var that = this;
        that.es.show();
        setTimeout(function () {
            var visibles = that.es.$list.find('li.es-visible');
            var oldSelected = that.es.$list.find('li.selected').removeClass('selected');
            var oldSelectedIndex = visibles.index(oldSelected);

            if (visibles.length > 0) {
                var selectedIndex = (visibles.length + index) % visibles.length;
                var selected = visibles.eq(selectedIndex);
                var top = selected.position().top;

                selected.addClass('selected');
                if (selectedIndex < oldSelectedIndex && top < 0)
                    that.es.$list.scrollTop(that.es.$list.scrollTop() + top);
                if (selectedIndex > oldSelectedIndex && top + selected.outerHeight() > that.es.$list.outerHeight())
                    that.es.$list.scrollTop(that.es.$list.scrollTop() + selected.outerHeight() + 2 * (top - that.es.$list.outerHeight()));
            }
        });
    };
    EditableSelectUtility.prototype.setAttributes = function ($element, attrs, data) {
        $.each(attrs || {}, function (i, attr) {
            $element.attr(attr.name, attr.value);
        });
        $element.data(data);
    };
    EditableSelectUtility.prototype.trigger = function (event) {
        var params = Array.prototype.slice.call(arguments, 1);
        var args = [event + '.editable-select'];
        args.push(params);
        this.es.$select.trigger.apply(this.es.$select, args);
        this.es.$input.trigger.apply(this.es.$input, args);
    };

    // Plugin
    Plugin = function (option) {
        var args = Array.prototype.slice.call(arguments, 1);
        return this.each(function () {
            var $this = $(this);
            var data = $this.data('editable-select');
            var options = $.extend({}, EditableSelect.DEFAULTS, $this.data(), typeof option == 'object' && option);

            if (!data) data = new EditableSelect(this, options);
            if (typeof option == 'string') data[option].apply(data, args);
        });
    }
    $.fn.editableSelect = Plugin;
    $.fn.editableSelect.Constructor = EditableSelect;

})(jQuery);
define("editable-select", function () {});